Skip to content

Commit

Permalink
Merge pull request #314 from OffchainLabs/fast-reorg-recovery
Browse files Browse the repository at this point in the history
Fast reorg recovery
  • Loading branch information
edfelten authored Jun 8, 2020
2 parents ef8d9b5 + cb82c6f commit cf92b05
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 30 deletions.
6 changes: 3 additions & 3 deletions packages/arb-provider-ethers/src/lib/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ export class ArbClient {
private _call(
callFunc: string,
contractAddress: string,
sender: string,
sender: string | undefined,
data: string
): Promise<Uint8Array> {
return new Promise((resolve, reject): void => {
Expand Down Expand Up @@ -273,15 +273,15 @@ export class ArbClient {

public call(
contractAddress: string,
sender: string,
sender: string | undefined,
data: string
): Promise<Uint8Array> {
return this._call('Validator.CallMessage', contractAddress, sender, data)
}

public pendingCall(
contractAddress: string,
sender: string,
sender: string | undefined,
data: string
): Promise<Uint8Array> {
return this._call('Validator.PendingCall', contractAddress, sender, data)
Expand Down
7 changes: 2 additions & 5 deletions packages/arb-provider-ethers/src/lib/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,19 +463,16 @@ export class ArbProvider extends ethers.providers.BaseProvider {
throw Error('Cannot create call without a destination')
}
const to = await transaction.to
let from = await transaction.from
const from = await transaction.from
const rawData = await transaction.data
if (!from) {
from = '0x1000000000000000000000000000000000000000'
}
let data = '0x'
if (rawData) {
data = ethers.utils.hexlify(rawData)
}

const callLatest = (
to: string,
from: string,
from: string | undefined,
data: string
): Promise<Uint8Array> => {
if (this.deterministicAssertions) {
Expand Down
36 changes: 21 additions & 15 deletions packages/arb-tx-aggregator/txaggregator/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,6 @@ func (m *Server) sendBatch(ctx context.Context) {

log.Println("Submitting batch with", len(txes), "transactions")

for _, tx := range txes {
log.Println("tx: ", tx)
}

err := m.globalInbox.DeliverTransactionBatchNoWait(
ctx,
m.rollupAddress,
Expand Down Expand Up @@ -147,7 +143,7 @@ func (m *Server) SendTransaction(
return nil, errors2.Wrap(err, "error decoding data")
}

pubkey, err := hexutil.Decode(args.Pubkey)
pubkeyBytes, err := hexutil.Decode(args.Pubkey)
if err != nil {
return nil, errors2.Wrap(err, "error decoding pubkey")
}
Expand Down Expand Up @@ -179,30 +175,40 @@ func (m *Server) SendTransaction(
messageHash := hashing.SoliditySHA3WithPrefix(txDataHash[:])

if !crypto.VerifySignature(
pubkey,
pubkeyBytes,
messageHash[:],
signature[:len(signature)-1],
) {
return nil, errors.New("Invalid signature")
}

m.Lock()
defer m.Unlock()

if !m.valid {
return nil, errors.New("Tx aggregator is not running")
}

var sigData [signatureLength]byte
copy(sigData[:], signature)

m.transactions = append(m.transactions, message.BatchTx{
tx := message.BatchTx{
To: to,
SeqNum: sequenceNum,
Value: valueInt,
Data: data,
Sig: sigData,
})
}

pubkey, err := crypto.DecompressPubkey(pubkeyBytes)
if err == nil {
sender := crypto.PubkeyToAddress(*pubkey)
log.Println("Got tx: ", tx, "from", hexutil.Encode(sender[:]))
} else {
log.Println("Got tx: ", tx, "from pubkey", hexutil.Encode(pubkeyBytes))
}

m.Lock()
defer m.Unlock()

if !m.valid {
return nil, errors.New("Tx aggregator is not running")
}

m.transactions = append(m.transactions, tx)

return &SendTransactionReply{}, nil
}
11 changes: 10 additions & 1 deletion packages/arb-validator-core/message/transactionBatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi"

"github.com/ethereum/go-ethereum/crypto"
"github.com/status-im/keycard-go/hexutils"

"github.com/offchainlabs/arbitrum/packages/arb-util/common"
"github.com/offchainlabs/arbitrum/packages/arb-util/hashing"
Expand Down Expand Up @@ -95,6 +95,15 @@ func NewBatchTxFromData(data []byte, offset int) (BatchTx, error) {
}, nil
}

func (b BatchTx) String() string {
return fmt.Sprintf("BatchTx(to: %v, seq: %v, value: %v, data: %v)",
b.To,
b.SeqNum,
b.Value,
hexutils.BytesToHex(b.Data),
)
}

func (b BatchTx) encodedLength() int {
return DataOffset + len(b.Data)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2019, Offchain Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package main

import (
"context"
"flag"
"log"
"os"
"time"

"github.com/offchainlabs/arbitrum/packages/arb-validator/cmdhelper"

"github.com/offchainlabs/arbitrum/packages/arb-validator-core/arbbridge"

"github.com/offchainlabs/arbitrum/packages/arb-validator/rollupmanager"

"github.com/offchainlabs/arbitrum/packages/arb-util/common"
)

// Launches the rollup validator with the following command line arguments:
// 1) Compiled Arbitrum bytecode file
// 2) private key file
// 3) Global EthBridge addresses json file
// 4) ethURL
func main() {
// Check number of args
flag.Parse()
switch os.Args[1] {
case "validate":
if err := cmdhelper.ValidateRollupChain("evil-arb-validator", createStressedManager); err != nil {
log.Fatal(err)
}
default:
}
}

func createStressedManager(rollupAddress common.Address, client arbbridge.ArbAuthClient, contractFile string, dbPath string) (*rollupmanager.Manager, error) {
return rollupmanager.CreateManager(
context.Background(),
rollupAddress,
rollupmanager.NewStressTestClient(client, time.Second*10),
contractFile,
dbPath,
)
}
3 changes: 2 additions & 1 deletion packages/arb-validator/rollupmanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func CreateManagerAdvanced(
man.listenersLock.Unlock()

currentProcessedBlockId := man.activeChain.CurrentBlockId()
time.Sleep(time.Second) // give time for things to settle, post-reorg, before restarting stuff

log.Println("Starting validator from", currentProcessedBlockId)

Expand Down Expand Up @@ -196,7 +197,7 @@ func CreateManagerAdvanced(
case <-ctx.Done():
return
default:
time.Sleep(10 * time.Second) // give time for things to settle, post-reorg, before restarting stuff

}
}
}()
Expand Down
12 changes: 7 additions & 5 deletions packages/arb-validator/rollupvalidator/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,14 @@ func (m *Server) executeCall(mach machine.Machine, args *validatorserver.CallMes
var contractAddress common.Address
copy(contractAddress[:], contractAddressBytes)

senderBytes, err := hexutil.Decode(args.Sender)
if err != nil {
return nil, err
}
var sender common.Address
copy(sender[:], senderBytes)
if len(args.Sender) > 0 {
senderBytes, err := hexutil.Decode(args.Sender)
if err != nil {
return nil, err
}
copy(sender[:], senderBytes)
}

callMsg := message.Call{
To: contractAddress,
Expand Down

0 comments on commit cf92b05

Please sign in to comment.