Skip to content

Commit

Permalink
Merge pull request #5174 from ethereum-optimism/develop
Browse files Browse the repository at this point in the history
Develop -> Master
  • Loading branch information
mslipper authored Mar 16, 2023
2 parents d5a63fa + 6d71335 commit bb6d28b
Show file tree
Hide file tree
Showing 39 changed files with 301 additions and 95 deletions.
5 changes: 0 additions & 5 deletions .changeset/chilled-melons-speak.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/flat-adults-hope.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/fluffy-geese-yell.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/long-frogs-study.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/metal-apes-taste.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/metal-feet-give.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/poor-buses-hug.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/quiet-crews-leave.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/sixty-days-explain.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/slimy-mangos-brake.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/three-apes-study.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/wicked-ads-pump.md

This file was deleted.

4 changes: 2 additions & 2 deletions integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
"devDependencies": {
"@babel/eslint-parser": "^7.5.4",
"@eth-optimism/contracts": "^0.5.40",
"@eth-optimism/contracts-bedrock": "0.13.0",
"@eth-optimism/contracts-bedrock": "0.13.1",
"@eth-optimism/contracts-periphery": "^1.0.7",
"@eth-optimism/core-utils": "0.12.0",
"@eth-optimism/sdk": "2.0.0",
"@eth-optimism/sdk": "2.0.1",
"@ethersproject/abstract-provider": "^5.7.0",
"@ethersproject/providers": "^5.7.0",
"@ethersproject/transactions": "^5.7.0",
Expand Down
11 changes: 10 additions & 1 deletion op-node/cmd/batch_decoder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ the transaction hash.
into channels. It then stores the channels with metadata on disk where the file name is the Channel ID.


### Force Close

`batch_decoder force-close` will create a transaction data that can be sent from the batcher address to
the batch inbox address which will force close the given channels. This will allow future channels to
be read without waiting for the channel timeout. It uses uses the results from `batch_decoder fetch` to
create the close transaction because the transaction it creates for a specific channel requires information
about if the channel has been closed or not. If it has been closed already but is missing specific frames
those frames need to be generated differently than simply closing the channel.


## JQ Cheat Sheet

`jq` is a really useful utility for manipulating JSON files.
Expand All @@ -48,7 +58,6 @@ jq "select(.is_ready == false)|[.id, .frames[0].inclusion_block, .frames[0].tran
## Roadmap

- Parallel transaction fetching (CLI-3563)
- Create force-close channel tx data from channel ID (CLI-3564)
- Pull the batches out of channels & store that information inside the ChannelWithMetadata (CLI-3565)
- Transaction Bytes used
- Total uncompressed (different from tx bytes) + compressed bytes
Expand Down
41 changes: 41 additions & 0 deletions op-node/cmd/batch_decoder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/fetch"
"github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/reassemble"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/urfave/cli"
Expand Down Expand Up @@ -113,6 +114,46 @@ func main() {
return nil
},
},
{
Name: "force-close",
Usage: "Create the tx data which will force close a channel",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Required: true,
Usage: "ID of the channel to close",
},
cli.StringFlag{
Name: "inbox",
Value: "0x0000000000000000000000000000000000000000",
Usage: "(Optional) Batch Inbox Address",
},
cli.StringFlag{
Name: "in",
Value: "/tmp/batch_decoder/transactions_cache",
Usage: "Cache directory for the found transactions",
},
},
Action: func(cliCtx *cli.Context) error {
var id derive.ChannelID
if err := (&id).UnmarshalText([]byte(cliCtx.String("id"))); err != nil {
log.Fatal(err)
}
frames := reassemble.LoadFrames(cliCtx.String("in"), common.HexToAddress(cliCtx.String("inbox")))
var filteredFrames []derive.Frame
for _, frame := range frames {
if frame.Frame.ID == id {
filteredFrames = append(filteredFrames, frame.Frame)
}
}
data, err := derive.ForceCloseTxData(filteredFrames)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%x\n", data)
return nil
},
},
}

if err := app.Run(os.Args); err != nil {
Expand Down
25 changes: 15 additions & 10 deletions op-node/cmd/batch_decoder/reassemble/reassemble.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,8 @@ type Config struct {
OutDirectory string
}

// Channels loads all transactions from the given input directory that are submitted to the
// specified batch inbox and then re-assembles all channels & writes the re-assembled channels
// to the out directory.
func Channels(config Config) {
if err := os.MkdirAll(config.OutDirectory, 0750); err != nil {
log.Fatal(err)
}
txns := loadTransactions(config.InDirectory, config.BatchInbox)
func LoadFrames(directory string, inbox common.Address) []FrameWithMetadata {
txns := loadTransactions(directory, inbox)
// Sort first by block number then by transaction index inside the block number range.
// This is to match the order they are processed in derivation.
sort.Slice(txns, func(i, j int) bool {
Expand All @@ -56,7 +50,17 @@ func Channels(config Config) {
}

})
frames := transactionsToFrames(txns)
return transactionsToFrames(txns)
}

// Channels loads all transactions from the given input directory that are submitted to the
// specified batch inbox and then re-assembles all channels & writes the re-assembled channels
// to the out directory.
func Channels(config Config) {
if err := os.MkdirAll(config.OutDirectory, 0750); err != nil {
log.Fatal(err)
}
frames := LoadFrames(config.InDirectory, config.BatchInbox)
framesByChannel := make(map[derive.ChannelID][]FrameWithMetadata)
for _, frame := range frames {
framesByChannel[frame.Frame.ID] = append(framesByChannel[frame.Frame.ID], frame)
Expand Down Expand Up @@ -143,6 +147,7 @@ func transactionsToFrames(txns []fetch.TransactionWithMetadata) []FrameWithMetad
return out
}

// if inbox is the zero address, it will load all frames
func loadTransactions(dir string, inbox common.Address) []fetch.TransactionWithMetadata {
files, err := os.ReadDir(dir)
if err != nil {
Expand All @@ -152,7 +157,7 @@ func loadTransactions(dir string, inbox common.Address) []fetch.TransactionWithM
for _, file := range files {
f := path.Join(dir, file.Name())
txm := loadTransactionsFile(f)
if txm.InboxAddr == inbox && txm.ValidSender {
if (inbox == common.Address{} || txm.InboxAddr == inbox) && txm.ValidSender {
out = append(out, txm)
}
}
Expand Down
55 changes: 55 additions & 0 deletions op-node/rollup/derive/channel_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,58 @@ func BlockToBatch(block *types.Block) (*BatchData, error) {
},
}, nil
}

// ForceCloseTxData generates the transaction data for a transaction which will force close
// a channel. It should be given every frame of that channel which has been submitted on
// chain. The frames should be given in order that they appear on L1.
func ForceCloseTxData(frames []Frame) ([]byte, error) {
if len(frames) == 0 {
return nil, errors.New("must provide at least one frame")
}
frameNumbers := make(map[uint16]struct{})
id := frames[0].ID
closeNumber := uint16(0)
closed := false
for i, frame := range frames {
if !closed && frame.IsLast {
closeNumber = frame.FrameNumber
}
closed = closed || frame.IsLast
frameNumbers[frame.FrameNumber] = struct{}{}
if frame.ID != id {
return nil, fmt.Errorf("invalid ID in list: first ID: %v, %vth ID: %v", id, i, frame.ID)
}
}

var out bytes.Buffer
out.WriteByte(DerivationVersion0)

if !closed {
f := Frame{
ID: id,
FrameNumber: 0,
Data: nil,
IsLast: true,
}
if err := f.MarshalBinary(&out); err != nil {
return nil, err
}
} else {
for i := uint16(0); i <= closeNumber; i++ {
if _, ok := frameNumbers[i]; ok {
continue
}
f := Frame{
ID: id,
FrameNumber: i,
Data: nil,
IsLast: false,
}
if err := f.MarshalBinary(&out); err != nil {
return nil, err
}
}
}

return out.Bytes(), nil
}
67 changes: 67 additions & 0 deletions op-node/rollup/derive/channel_out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math/big"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -49,3 +50,69 @@ func TestRLPByteLimit(t *testing.T) {
require.Equal(t, err, rlp.ErrValueTooLarge)
require.Equal(t, out2, "")
}

func TestForceCloseTxData(t *testing.T) {
id := [16]byte{0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}
tests := []struct {
frames []Frame
errors bool
output string
}{
{
frames: []Frame{},
errors: true,
output: "",
},
{
frames: []Frame{Frame{FrameNumber: 0, IsLast: false}, Frame{ID: id, FrameNumber: 1, IsLast: true}},
errors: true,
output: "",
},
{
frames: []Frame{Frame{ID: id, FrameNumber: 0, IsLast: false}},
errors: false,
output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000001",
},
{
frames: []Frame{Frame{ID: id, FrameNumber: 0, IsLast: true}},
errors: false,
output: "00",
},
{
frames: []Frame{Frame{ID: id, FrameNumber: 1, IsLast: false}},
errors: false,
output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000001",
},
{
frames: []Frame{Frame{ID: id, FrameNumber: 1, IsLast: true}},
errors: false,
output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000000",
},
{
frames: []Frame{Frame{ID: id, FrameNumber: 2, IsLast: true}},
errors: false,
output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000000deadbeefdeadbeefdeadbeefdeadbeef00010000000000",
},
{
frames: []Frame{Frame{ID: id, FrameNumber: 1, IsLast: false}, Frame{ID: id, FrameNumber: 3, IsLast: true}},
errors: false,
output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000000deadbeefdeadbeefdeadbeefdeadbeef00020000000000",
},
{
frames: []Frame{Frame{ID: id, FrameNumber: 1, IsLast: false}, Frame{ID: id, FrameNumber: 3, IsLast: true}, Frame{ID: id, FrameNumber: 5, IsLast: true}},
errors: false,
output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000000deadbeefdeadbeefdeadbeefdeadbeef00020000000000",
},
}

for i, test := range tests {
out, err := ForceCloseTxData(test.frames)
if test.errors {
require.NotNil(t, err, "Should error on tc %v", i)
require.Nil(t, out, "Should return no value in tc %v", i)
} else {
require.NoError(t, err, "Should not error on tc %v", i)
require.Equal(t, common.FromHex(test.output), out, "Should match output tc %v", i)
}
}
}
10 changes: 10 additions & 0 deletions packages/actor-tests/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# @eth-optimism/actor-tests

## 0.0.23

### Patch Changes

- Updated dependencies [22c3885f5]
- Updated dependencies [66cafc00a]
- Updated dependencies [f52c07529]
- @eth-optimism/contracts-bedrock@0.13.1
- @eth-optimism/sdk@2.0.1

## 0.0.22

### Patch Changes
Expand Down
6 changes: 3 additions & 3 deletions packages/actor-tests/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eth-optimism/actor-tests",
"version": "0.0.22",
"version": "0.0.23",
"description": "A library and suite of tests to stress test Optimism Bedrock.",
"license": "MIT",
"author": "",
Expand All @@ -18,9 +18,9 @@
"test:coverage": "yarn test"
},
"dependencies": {
"@eth-optimism/contracts-bedrock": "0.13.0",
"@eth-optimism/contracts-bedrock": "0.13.1",
"@eth-optimism/core-utils": "^0.12.0",
"@eth-optimism/sdk": "^2.0.0",
"@eth-optimism/sdk": "^2.0.1",
"@types/chai": "^4.2.18",
"@types/chai-as-promised": "^7.1.4",
"async-mutex": "^0.3.2",
Expand Down
Loading

0 comments on commit bb6d28b

Please sign in to comment.