Skip to content
This repository has been archived by the owner on May 11, 2024. It is now read-only.

Commit

Permalink
feat: merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
alexshliu committed Sep 27, 2023
2 parents ba141e8 + f192e0a commit c5e4fa2
Show file tree
Hide file tree
Showing 25 changed files with 561 additions and 339 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,10 @@ jobs:
working-directory: ${{ env.TAIKO_MONO_DIR }}
run: cd ./packages/protocol && pnpm install && ./script/download_solc.sh && forge install

- name: Build
working-directory: ${{ env.CLIENT_DIR }}
run: make build

- name: Test
working-directory: ${{ env.CLIENT_DIR }}
run: |
TAIKO_MONO_DIR=${GITHUB_WORKSPACE}/${TAIKO_MONO_DIR} COMPILE_PROTOCOL=true make test
TAIKO_MONO_DIR=${GITHUB_WORKSPACE}/${TAIKO_MONO_DIR} make test
- name: Codecov.io
uses: codecov/codecov-action@v3
Expand Down
14 changes: 14 additions & 0 deletions cmd/flags/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@ var (
Usage: "Gas limit will be used for TaikoL1.proveBlock transactions",
Category: proverCategory,
}
ProveBlockTxReplacementMultiplier = &cli.Uint64Flag{
Name: "proveBlockTxReplacementMultiplier",
Value: 2,
Usage: "Gas tip multiplier when replacing a TaikoL1.proveBlock transaction with same nonce",
Category: proverCategory,
}
ProveBlockMaxTxGasTipCap = &cli.Uint64Flag{
Name: "proveBlockMaxTxGasTipCap",
Usage: "Gas tip cap (in wei) for a TaikoL1.proveBlock transaction when doing the transaction replacement",
Category: proverCategory,
}
ProverHTTPServerPort = &cli.Uint64Flag{
Name: "prover.httpServerPort",
Usage: "Port to expose for http server",
Expand Down Expand Up @@ -142,11 +153,14 @@ var ProverFlags = MergeFlags(CommonFlags, []cli.Flag{
OracleProverPrivateKey,
OracleProofSubmissionDelay,
ProofSubmissionMaxRetry,
ProveBlockTxReplacementMultiplier,
ProveBlockMaxTxGasTipCap,
Graffiti,
CheckProofWindowExpiredInterval,
ProveUnassignedBlocks,
ProveBlockTxGasLimit,
ProverHTTPServerPort,
ProverCapacity,
MaxExpiry,
TaikoTokenAddress,
})
29 changes: 17 additions & 12 deletions driver/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,38 +33,42 @@ func (s *DriverTestSuite) TestNewConfigFromCliContext() {
s.Equal(rpcTimeout, *c.RPCTimeout)
s.NotEmpty(c.JwtSecret)
s.Nil(new(Driver).InitFromCli(context.Background(), ctx))
s.True(c.P2PSyncVerifiedBlocks)
s.Equal("http://localhost:8545", c.L2CheckPoint)

return err
}

s.Nil(app.Run([]string{
"TestNewConfigFromCliContext",
"-" + flags.L1WSEndpoint.Name, l1Endpoint,
"-" + flags.L2WSEndpoint.Name, l2Endpoint,
"-" + flags.L2AuthEndpoint.Name, l2EngineEndpoint,
"-" + flags.TaikoL1Address.Name, taikoL1,
"-" + flags.TaikoL2Address.Name, taikoL2,
"-" + flags.JWTSecret.Name, os.Getenv("JWT_SECRET"),
"-" + flags.P2PSyncTimeout.Name, "120",
"-" + flags.RPCTimeout.Name, "5",
"--" + flags.L1WSEndpoint.Name, l1Endpoint,
"--" + flags.L2WSEndpoint.Name, l2Endpoint,
"--" + flags.L2AuthEndpoint.Name, l2EngineEndpoint,
"--" + flags.TaikoL1Address.Name, taikoL1,
"--" + flags.TaikoL2Address.Name, taikoL2,
"--" + flags.JWTSecret.Name, os.Getenv("JWT_SECRET"),
"--" + flags.P2PSyncTimeout.Name, "120",
"--" + flags.RPCTimeout.Name, "5",
"--" + flags.P2PSyncVerifiedBlocks.Name,
"--" + flags.CheckPointSyncUrl.Name, "http://localhost:8545",
}))
}

func (s *DriverTestSuite) TestNewConfigFromCliContextJWTError() {
app := s.SetupApp()
s.ErrorContains(app.Run([]string{
"TestNewConfigFromCliContext",
"-" + flags.JWTSecret.Name, "wrongsecretfile.txt",
"--" + flags.JWTSecret.Name, "wrongsecretfile.txt",
}), "invalid JWT secret file")
}

func (s *DriverTestSuite) TestNewConfigFromCliContextEmptyL2CheckPoint() {
app := s.SetupApp()
s.ErrorContains(app.Run([]string{
"TestNewConfigFromCliContext",
"-" + flags.JWTSecret.Name, os.Getenv("JWT_SECRET"),
"-" + flags.P2PSyncVerifiedBlocks.Name, "true",
"-" + flags.L2WSEndpoint.Name, "",
"--" + flags.JWTSecret.Name, os.Getenv("JWT_SECRET"),
"--" + flags.P2PSyncVerifiedBlocks.Name,
"--" + flags.L2WSEndpoint.Name, "",
}), "empty L2 check point URL")
}

Expand All @@ -80,6 +84,7 @@ func (s *DriverTestSuite) SetupApp() *cli.App {
&cli.BoolFlag{Name: flags.P2PSyncVerifiedBlocks.Name},
&cli.UintFlag{Name: flags.P2PSyncTimeout.Name},
&cli.UintFlag{Name: flags.RPCTimeout.Name},
&cli.StringFlag{Name: flags.CheckPointSyncUrl.Name},
}
app.Action = func(ctx *cli.Context) error {
_, err := NewConfigFromCliContext(ctx)
Expand Down
2 changes: 0 additions & 2 deletions integration_test/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ if ! docker info >/dev/null 2>&1; then
fi

TESTNET_CONFIG=$DIR/nodes/docker-compose.yml
COMPILE_PROTOCOL=${COMPILE_PROTOCOL:-false}
PREMINT_TOKEN_AMOUNT=92233720368547758070000000000000

TESTNET_CONFIG=$TESTNET_CONFIG \
COMPILE_PROTOCOL=$COMPILE_PROTOCOL \
TAIKO_MONO_DIR=$TAIKO_MONO_DIR \
PREMINT_TOKEN_AMOUNT=$PREMINT_TOKEN_AMOUNT \
$DIR/nodes/init.sh
Expand Down
Empty file.
15 changes: 3 additions & 12 deletions integration_test/nodes/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,10 @@ echo "Starting testnet..."
docker compose -f $TESTNET_CONFIG down -v --remove-orphans &>/dev/null
docker compose -f $TESTNET_CONFIG up -d

if [ "$COMPILE_PROTOCOL" == "true" ]; then
cd $TAIKO_MONO_DIR/packages/protocol && yarn run clean && yarn run compile
cd -
fi

echo "Waiting till testnet nodes fully started..."

NODE_URL=localhost:18545 $DIR/../util/wait_for_node.sh
NODE_URL=localhost:28545 $DIR/../util/wait_for_node.sh
rm -rf $DIR/deployments/mainnet.json

# Get the hash of L2 genesis.
L2_GENESIS_HASH=$(
Expand All @@ -38,21 +32,18 @@ L2_GENESIS_HASH=$(

# Deploy Taiko protocol.
cd $TAIKO_MONO_DIR/packages/protocol &&
PRIVATE_KEY=ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
ORACLE_PROVER=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 \
SOLO_PROPOSER=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 \
OWNER=0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC \
TREASURY=0xdf09A0afD09a63fb04ab3573922437e1e637dE8b \
TAIKO_L2_ADDRESS=0x1000777700000000000000000000000000000001 \
L2_SIGNAL_SERVICE=0x1000777700000000000000000000000000000007 \
SHARED_SIGNAL_SERVICE=0x0000000000000000000000000000000000000000 \
TAIKO_TOKEN_PREMINT_RECIPIENTS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266,0x70997970C51812dc3A010C7d01b50e0d17dc79C8 \
TAIKO_TOKEN_PREMINT_RECIPIENTS="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266,0x70997970C51812dc3A010C7d01b50e0d17dc79C8" \
TAIKO_TOKEN_PREMINT_AMOUNTS=$PREMINT_TOKEN_AMOUNT,$PREMINT_TOKEN_AMOUNT \
L2_GENESIS_HASH=$L2_GENESIS_HASH \
L2_CHAIN_ID=167001 \
forge script script/DeployOnL1.s.sol:DeployOnL1 \
--fork-url http://localhost:18545 \
--broadcast \
--ffi \
-vvvv \
-vvvvv \
--block-gas-limit 100000000
103 changes: 103 additions & 0 deletions pkg/rpc/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient/gethclient"
"github.com/ethereum/go-ethereum/log"
Expand All @@ -36,6 +37,59 @@ func GetProtocolStateVariables(
return &stateVars, nil
}

// CheckProverBalance checks if the prover has the necessary balance either in TaikoL1 token balances
// or, if not, then check allowance, as contract will attempt to burn directly after
// if it doesnt have the available token balance in-contract.
func CheckProverBalance(
ctx context.Context,
rpc *Client,
prover common.Address,
taikoL1Address common.Address,
bond *big.Int,
) (bool, error) {
ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout)
defer cancel()

depositedBalance, err := rpc.TaikoL1.GetTaikoTokenBalance(&bind.CallOpts{Context: ctxWithTimeout}, prover)
if err != nil {
return false, err
}

log.Info("Prover's deposited taikoTokenBalance", "balance", depositedBalance.String(), "address", prover.Hex())

if bond.Cmp(depositedBalance) > 0 {
// Check allowance on taiko token contract
allowance, err := rpc.TaikoToken.Allowance(&bind.CallOpts{Context: ctxWithTimeout}, prover, taikoL1Address)
if err != nil {
return false, err
}

log.Info("Prover allowance for TaikoL1 contract", "allowance", allowance.String(), "address", prover.Hex())

// Check prover's taiko token balance
balance, err := rpc.TaikoToken.BalanceOf(&bind.CallOpts{Context: ctxWithTimeout}, prover)
if err != nil {
return false, err
}

log.Info("Prover's wallet taiko token balance", "balance", balance.String(), "address", prover.Hex())

if bond.Cmp(allowance) > 0 || bond.Cmp(balance) > 0 {
log.Info(
"Assigned prover does not have required on-chain token balance or allowance",
"providedProver", prover.Hex(),
"depositedBalance", depositedBalance.String(),
"taikoTokenBalance", balance,
"allowance", allowance.String(),
"proofBond", bond,
)
return false, nil
}
}

return true, nil
}

// WaitReceipt keeps waiting until the given transaction has an execution
// receipt to know whether it was reverted or not.
func WaitReceipt(
Expand Down Expand Up @@ -147,6 +201,55 @@ func ContentFrom(
)
}

// IncreaseGasTipCap tries to increase the given transaction's gasTipCap.
func IncreaseGasTipCap(
ctx context.Context,
cli *Client,
opts *bind.TransactOpts,
address common.Address,
txReplacementTipMultiplier *big.Int,
maxGasTipCap *big.Int,
) (*bind.TransactOpts, error) {
ctxWithTimeout, cancel := ctxWithTimeoutOrDefault(ctx, defaultTimeout)
defer cancel()

log.Info("Try replacing a transaction with same nonce", "sender", address, "nonce", opts.Nonce)

originalTx, err := GetPendingTxByNonce(ctxWithTimeout, cli, address, opts.Nonce.Uint64())
if err != nil || originalTx == nil {
log.Warn(
"Original transaction not found",
"sender", address,
"nonce", opts.Nonce,
"error", err,
)

opts.GasTipCap = new(big.Int).Mul(opts.GasTipCap, txReplacementTipMultiplier)
} else {
log.Info(
"Original transaction to replace",
"sender", address,
"nonce", opts.Nonce,
"gasTipCap", originalTx.GasTipCap(),
"gasFeeCap", originalTx.GasFeeCap(),
)

opts.GasTipCap = new(big.Int).Mul(originalTx.GasTipCap(), txReplacementTipMultiplier)
}

if maxGasTipCap != nil && opts.GasTipCap.Cmp(maxGasTipCap) > 0 {
log.Info(
"New gasTipCap exceeds limit, keep waiting",
"multiplier", txReplacementTipMultiplier,
"newGasTipCap", opts.GasTipCap,
"maxTipCap", maxGasTipCap,
)
return nil, txpool.ErrReplaceUnderpriced
}

return opts, nil
}

// GetPendingTxByNonce tries to retrieve a pending transaction with a given nonce in a node's mempool.
func GetPendingTxByNonce(
ctx context.Context,
Expand Down
Loading

0 comments on commit c5e4fa2

Please sign in to comment.