Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into siliev/contract-upgra…
Browse files Browse the repository at this point in the history
…des-bridge
  • Loading branch information
StefanIliev545 committed Jun 6, 2024
2 parents d2fd40a + e645308 commit be732ee
Show file tree
Hide file tree
Showing 12 changed files with 287 additions and 37 deletions.
139 changes: 139 additions & 0 deletions .github/workflows/manual-deploy-dexynth-gateway.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Deploys Ten Gateway for Dexynth on Azure for Testnet
# Builds the Ten Gateway image, pushes the image to dockerhub and starts the Obscuro Gateway on Azure VM

name: '[M] Deploy Ten Gateway Dexynth'
run-name: '[M] Deploy Ten Gateway Dexynth ( ${{ github.event.inputs.testnet_type }} )'
on:
workflow_dispatch:
inputs:
testnet_type:
description: 'Testnet Type'
required: true
default: 'sepolia-testnet'
type: choice
options:
- 'sepolia-testnet'

jobs:
build-and-deploy-dexynth:
runs-on: ubuntu-latest
environment:
name: {{ github.event.inputs.testnet_type }}
steps:
- name: 'Print GitHub variables'
# This is a useful record of what the environment variables were at the time the job ran, for debugging and reference
run: |
echo "GitHub Variables = ${{ toJSON(vars) }}"
- uses: actions/checkout@v3

- name: 'Extract branch name'
shell: bash
run: |
echo "Branch Name: ${GITHUB_REF_NAME}"
echo "BRANCH_NAME=${GITHUB_REF_NAME}" >> $GITHUB_ENV
- name: 'Set up Docker'
uses: docker/setup-buildx-action@v1

- name: 'Login to Azure docker registry'
uses: azure/docker-login@v1
with:
login-server: testnetobscuronet.azurecr.io
username: testnetobscuronet
password: ${{ secrets.REGISTRY_PASSWORD }}

- name: 'Login via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Build and Push Docker Image
run: |
DOCKER_BUILDKIT=1 docker build --build-arg TESTNET_TYPE=${{ github.event.inputs.testnet_type }} -t ${{ vars.DOCKER_BUILD_TAG_GATEWAY_DEXYNTH }} -f ./tools/walletextension/Dockerfile .
docker push ${{ vars.DOCKER_BUILD_TAG_GATEWAY_DEXYNTH }}
# This will fail some deletions due to resource dependencies ( ie. you must first delete the vm before deleting the disk)
- name: 'Delete deployed VMs'
uses: azure/CLI@v1
with:
inlineScript: |
$(az resource list --tag ${{ vars.AZURE_DEPLOY_GROUP_GATEWAY_DEXYNTH }}=true --query '[]."id"' -o tsv | xargs -n1 az resource delete --verbose -g Testnet --ids) || true
# This will clean up any lingering dependencies - might fail if there are no resources to cleanup
- name: 'Delete VMs dependencies'
uses: azure/CLI@v1
with:
inlineScript: |
$(az resource list --tag ${{ vars.AZURE_DEPLOY_GROUP_GATEWAY_DEXYNTH }}=true --query '[]."id"' -o tsv | xargs -n1 az resource delete --verbose -g Testnet --ids) || true
- name: 'Ensure VM Static Public IP Exists'
uses: azure/CLI@v1
with:
inlineScript: |
az network public-ip show -g Testnet -n "${{ github.event.inputs.testnet_type }}-OG-static-dexynth" || az network public-ip create -g Testnet -n "${{ github.event.inputs.testnet_type }}-OG-static-dexynth" --allocation-method Static --sku Standard
- name: 'Assign/Update DNS Name for Public IP'
uses: azure/CLI@v1
with:
inlineScript: |
existing_dns_name=$(az network public-ip show -g Testnet -n "${{ github.event.inputs.testnet_type }}-OG-static-dexynth" --query dnsSettings.domainNameLabel -o tsv)
if [ -z "$existing_dns_name" ]; then
az network public-ip update -g Testnet -n "${{ github.event.inputs.testnet_type }}-OG-static-dexynth" --dns-name "obscurogateway-${{ github.event.inputs.testnet_type }}-dexynth"
fi
- name: 'Create VM for Gateway node on Azure'
uses: azure/CLI@v1
with:
inlineScript: |
az vm create -g Testnet -n "${{ github.event.inputs.testnet_type }}-OG-${{ GITHUB.RUN_NUMBER }}-dexynth" \
--admin-username obscurouser --admin-password "${{ secrets.OBSCURO_NODE_VM_PWD }}" \
--public-ip-address "${{ github.event.inputs.testnet_type }}-OG-static-dexynth" \
--tags deploygroup=ObscuroGateway-${{ github.event.inputs.testnet_type }}-${{ GITHUB.RUN_NUMBER }}-dexynth ${{ vars.AZURE_DEPLOY_GROUP_GATEWAY_DEXYNTH }}=true \
--vnet-name ObscuroGateway-${{ github.event.inputs.testnet_type }}-dexynth-01VNET --subnet ObscuroGateway-${{ github.event.inputs.testnet_type }}-dexynth-01Subnet \
--size Standard_D4_v5 --image Canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest \
--authentication-type password
- name: 'Open Obscuro node-${{ matrix.host_id }} ports on Azure'
uses: azure/CLI@v1
with:
inlineScript: |
az vm open-port -g Testnet -n "${{ github.event.inputs.testnet_type }}-OG-${{ GITHUB.RUN_NUMBER }}-dexynth" --port 80,81
# To overcome issues with critical VM resources being unavailable, we need to wait for the VM to be ready
- name: 'Allow time for VM initialization'
shell: bash
run: sleep 30

- name: 'Start Obscuro gateway on Azure'
uses: azure/CLI@v1
with:
inlineScript: |
az vm run-command invoke -g Testnet -n "${{ github.event.inputs.testnet_type }}-OG-${{ GITHUB.RUN_NUMBER }}-dexynth" \
--command-id RunShellScript \
--scripts 'mkdir -p /home/obscuro \
&& sudo apt-get update \
&& sudo apt-get install -y gcc \
&& sudo snap refresh && sudo snap install --channel=1.18 go --classic \
&& curl -fsSL https://get.docker.com -o get-docker.sh && sh ./get-docker.sh \
&& git clone --depth 1 -b ${{ env.BRANCH_NAME }} https://github.com/ten-protocol/go-ten.git /home/obscuro/go-obscuro \
&& docker network create --driver bridge node_network || true \
&& docker run -d --name datadog-agent \
--network node_network \
-e DD_API_KEY=${{ secrets.DD_API_KEY }} \
-e DD_LOGS_ENABLED=true \
-e DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL=true \
-e DD_LOGS_CONFIG_AUTO_MULTI_LINE_DETECTION=true \
-e DD_CONTAINER_EXCLUDE_LOGS="name:datadog-agent" \
-e DD_SITE="datadoghq.eu" \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /proc/:/host/proc/:ro \
-v /opt/datadog-agent/run:/opt/datadog-agent/run:rw \
-v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro \
datadog/agent:latest \
&& cd /home/obscuro/go-obscuro/ \
&& docker run -d -p 80:80 -p 81:81 --name ${{ github.event.inputs.testnet_type }}-OG-${{ GITHUB.RUN_NUMBER }}-dexynth \
-e OBSCURO_GATEWAY_VERSION="${{ GITHUB.RUN_NUMBER }}-${{ GITHUB.SHA }}" \
${{ vars.DOCKER_BUILD_TAG_GATEWAY_DEXYNTH }} \
-host=0.0.0.0 -port=8080 -portWS=81 -nodeHost=${{ vars.L2_RPC_URL_VALIDATOR_DEXYNTH }} -verbose=true \
-logPath=sys_out -dbType=mariaDB -dbConnectionURL="obscurouser:${{ secrets.OBSCURO_GATEWAY_MARIADB_USER_PWD }}@tcp(obscurogateway-mariadb-${{ github.event.inputs.testnet_type }}.uksouth.cloudapp.azure.com:3306)/ogdb"'
12 changes: 10 additions & 2 deletions go/enclave/evm/evm_facade.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import (
gethrpc "github.com/ten-protocol/go-ten/lib/gethfork/rpc"
)

var ErrGasNotEnoughForL1 = errors.New("gas limit too low to pay for execution and l1 fees")

// ExecuteTransactions
// header - the header of the rollup where this transaction will be included
// fromTxIndex - for the receipts and events, the evm needs to know for each transaction the order in which it was executed in the block.
Expand Down Expand Up @@ -91,7 +93,12 @@ func ExecuteTransactions(
if err != nil {
tCountRollback++
result[t.Tx.Hash()] = err
logger.Info("Failed to execute tx:", log.TxKey, t.Tx.Hash(), log.CtrErrKey, err)
// only log tx execution errors if they are unexpected
logFailedTx := logger.Info
if errors.Is(err, gethcore.ErrNonceTooHigh) || errors.Is(err, gethcore.ErrNonceTooLow) || errors.Is(err, gethcore.ErrFeeCapTooLow) || errors.Is(err, ErrGasNotEnoughForL1) {
logFailedTx = logger.Debug
}
logFailedTx("Failed to execute tx:", log.TxKey, t.Tx.Hash(), log.CtrErrKey, err)
continue
}
result[t.Tx.Hash()] = r
Expand Down Expand Up @@ -160,8 +167,9 @@ func executeTransaction(

// The gas limit of the transaction (evm message) should always be higher than the gas overhead
// used to cover the l1 cost
// todo - this check has to be added to the mempool as well
if msg.GasLimit < l1Gas.Uint64() {
return nil, fmt.Errorf("gas limit set by user is too low to pay for execution and l1 fees. Want at least: %d have: %d", l1Gas, msg.GasLimit)
return nil, fmt.Errorf("%w. Want at least: %d have: %d", ErrGasNotEnoughForL1, l1Gas, msg.GasLimit)
}

// Remove the gas overhead for l1 publishing from the gas limit in order to define
Expand Down
6 changes: 4 additions & 2 deletions go/enclave/rpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ type RPCServer struct {
// NewEnclaveRPCServer prepares an enclave RPCServer (doesn't start listening until `StartServer` is called
func NewEnclaveRPCServer(listenAddress string, enclave common.Enclave, logger gethlog.Logger) *RPCServer {
return &RPCServer{
enclave: enclave,
grpcServer: grpc.NewServer(),
enclave: enclave,
grpcServer: grpc.NewServer(
grpc.MaxRecvMsgSize(1024 * 1024 * 50),
),
logger: logger,
listenAddress: listenAddress,
}
Expand Down
6 changes: 3 additions & 3 deletions go/enclave/storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,13 +370,13 @@ func (s *storageImpl) IsBlockAncestor(ctx context.Context, block *types.Block, m

func (s *storageImpl) HealthCheck(ctx context.Context) (bool, error) {
defer s.logDuration("HealthCheck", measure.NewStopwatch())
headBatch, err := s.FetchHeadBatch(ctx)
seqNo, err := s.FetchCurrentSequencerNo(ctx)
if err != nil {
return false, err
}

if headBatch == nil {
return false, fmt.Errorf("head batch is nil")
if seqNo == nil {
return false, fmt.Errorf("no batches are stored")
}

return true, nil
Expand Down
19 changes: 13 additions & 6 deletions go/enclave/txpool/txpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import (
"math/big"
"strings"
"sync"
_ "unsafe"

gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"

// unsafe package imported in order to link to a private function in go-ethereum.
// This allows us to validate transactions against the tx pool rules.
_ "unsafe"

gethlog "github.com/ethereum/go-ethereum/log"
"github.com/ten-protocol/go-ten/go/common/log"

gethcommon "github.com/ethereum/go-ethereum/common"
gethtxpool "github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
"github.com/ethereum/go-ethereum/core/types"
Expand Down Expand Up @@ -51,7 +53,7 @@ func NewTxPool(blockchain *ethchainadapter.EthChainAdapter, gasTip *big.Int, log
// Start starts the pool
// can only be started after t.blockchain has at least one block inside
func (t *TxPool) Start() error {
if t.pool != nil {
if t.running {
return fmt.Errorf("tx pool already started")
}

Expand All @@ -67,14 +69,19 @@ func (t *TxPool) Start() error {

// PendingTransactions returns all pending transactions grouped per address and ordered per nonce
func (t *TxPool) PendingTransactions() map[gethcommon.Address][]*gethtxpool.LazyTransaction {
// todo
// todo - for now using the base fee from the block
baseFee := t.Chain.CurrentBlock().BaseFee
return t.pool.Pending(gethtxpool.PendingFilter{
// BaseFee:
BaseFee: uint256.NewInt(baseFee.Uint64()),
OnlyPlainTxs: true,
})
}

// Add adds a new transactions to the pool
func (t *TxPool) Add(transaction *common.L2Tx) error {
if !t.running {
return fmt.Errorf("tx pool not running")
}
var strErrors []string
for _, err := range t.pool.Add([]*types.Transaction{transaction}, false, false) {
if err != nil {
Expand Down Expand Up @@ -118,5 +125,5 @@ func (t *TxPool) Close() error {
t.logger.Error("Could not close legacy pool", log.ErrKey, err)
}
}()
return t.legacyPool.Close()
return t.pool.Close()
}
14 changes: 6 additions & 8 deletions go/ethadapter/geth_rpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,16 @@ func (e *gethRPCClient) FetchLastBatchSeqNo(address gethcommon.Address) (*big.In

// PrepareTransactionToSend takes a txData type and overrides the From, Gas and Gas Price field with current values
func (e *gethRPCClient) PrepareTransactionToSend(ctx context.Context, txData types.TxData, from gethcommon.Address) (types.TxData, error) {
return e.PrepareTransactionToRetry(ctx, txData, from, 0)
nonce, err := e.EthClient().PendingNonceAt(ctx, from)
if err != nil {
return nil, fmt.Errorf("could not get nonce - %w", err)
}
return e.PrepareTransactionToRetry(ctx, txData, from, nonce, 0)
}

// PrepareTransactionToRetry takes a txData type and overrides the From, Gas and Gas Price field with current values
// it bumps the price by a multiplier for retries. retryNumber is zero on first attempt (no multiplier on price)
func (e *gethRPCClient) PrepareTransactionToRetry(ctx context.Context, txData types.TxData, from gethcommon.Address, retryNumber int) (types.TxData, error) {
func (e *gethRPCClient) PrepareTransactionToRetry(ctx context.Context, txData types.TxData, from gethcommon.Address, nonce uint64, retryNumber int) (types.TxData, error) {
unEstimatedTx := types.NewTx(txData)
gasPrice, err := e.EthClient().SuggestGasPrice(ctx)
if err != nil {
Expand Down Expand Up @@ -279,12 +283,6 @@ func (e *gethRPCClient) PrepareTransactionToRetry(ctx context.Context, txData ty
return nil, fmt.Errorf("could not estimate gas - %w", err)
}

// we fetch the current nonce on every retry to avoid any risk of nonce reuse/conflicts
nonce, err := e.EthClient().PendingNonceAt(ctx, from)
if err != nil {
return nil, fmt.Errorf("could not fetch nonce - %w", err)
}

return &types.LegacyTx{
Nonce: nonce,
GasPrice: retryPrice,
Expand Down
2 changes: 1 addition & 1 deletion go/ethadapter/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type EthClient interface {

// PrepareTransactionToSend updates the tx with from address, current nonce and current estimates for the gas and the gas price
PrepareTransactionToSend(ctx context.Context, txData types.TxData, from gethcommon.Address) (types.TxData, error)
PrepareTransactionToRetry(ctx context.Context, txData types.TxData, from gethcommon.Address, retries int) (types.TxData, error)
PrepareTransactionToRetry(ctx context.Context, txData types.TxData, from gethcommon.Address, nonce uint64, retries int) (types.TxData, error)

FetchLastBatchSeqNo(address gethcommon.Address) (*big.Int, error)

Expand Down
9 changes: 8 additions & 1 deletion go/host/l1/publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,12 +391,19 @@ func (p *Publisher) publishTransaction(tx types.TxData) error {

retries := -1

// we keep trying to send the transaction with this nonce until it is included in a block
// note: this is only safe because of the sendingLock guaranteeing only one transaction in-flight at a time
nonce, err := p.ethClient.Nonce(p.hostWallet.Address())
if err != nil {
return fmt.Errorf("could not get nonce for L1 tx: %w", err)
}

// while the publisher service is still alive we keep trying to get the transaction into the L1
for !p.hostStopper.IsStopping() {
retries++ // count each attempt so we can increase gas price

// update the tx gas price before each attempt
tx, err := p.ethClient.PrepareTransactionToRetry(p.sendingContext, tx, p.hostWallet.Address(), retries)
tx, err := p.ethClient.PrepareTransactionToRetry(p.sendingContext, tx, p.hostWallet.Address(), nonce, retries)
if err != nil {
return errors.Wrap(err, "could not estimate gas/gas price for L1 tx")
}
Expand Down
2 changes: 1 addition & 1 deletion go/host/rpc/enclaverpc/enclave_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ func (c *Client) StreamL2Updates() (chan common.StreamL2UpdatesResponse, func())
batchChan := make(chan common.StreamL2UpdatesResponse, 10)
cancelCtx, cancel := context.WithCancel(context.Background())

stream, err := c.protoClient.StreamL2Updates(cancelCtx, &generated.StreamL2UpdatesRequest{})
stream, err := c.protoClient.StreamL2Updates(cancelCtx, &generated.StreamL2UpdatesRequest{}, grpc.MaxCallRecvMsgSize(1024*1024*50))
if err != nil {
c.logger.Error("Error opening batch stream.", log.ErrKey, err)
cancel()
Expand Down
2 changes: 1 addition & 1 deletion integration/ethereummock/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (m *Node) PrepareTransactionToSend(_ context.Context, txData types.TxData,
}, nil
}

func (m *Node) PrepareTransactionToRetry(ctx context.Context, txData types.TxData, from gethcommon.Address, _ int) (types.TxData, error) {
func (m *Node) PrepareTransactionToRetry(ctx context.Context, txData types.TxData, from gethcommon.Address, _ uint64, _ int) (types.TxData, error) {
return m.PrepareTransactionToSend(ctx, txData, from)
}

Expand Down
17 changes: 8 additions & 9 deletions integration/networktest/env/network_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,14 @@ func (t *testnetEnv) startTenGateway() {
TenChainID: integration.TenChainID,
}
tenGWContainer := walletextension.NewContainerFromConfig(cfg, t.logger)
go func() {
fmt.Println("Starting Ten Gateway, HTTP Port:", _gwHTTPPort, "WS Port:", _gwWSPort)
err := tenGWContainer.Start()
if err != nil {
t.logger.Error("failed to start ten gateway", "err", err)
panic(err)
}
t.tenGatewayContainer = tenGWContainer
}()

fmt.Println("Starting Ten Gateway, HTTP Port:", _gwHTTPPort, "WS Port:", _gwWSPort)
err := tenGWContainer.Start()
if err != nil {
t.logger.Error("failed to start ten gateway", "err", err)
panic(err)
}
t.tenGatewayContainer = tenGWContainer
t.testnetConnector.tenGatewayURL = fmt.Sprintf("http://localhost:%d", _gwHTTPPort)
}

Expand Down
Loading

0 comments on commit be732ee

Please sign in to comment.