Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions miner/verify_bundles.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ func checkBundlesAtomicity(
var (
firstTxBlockIdx int
firstTxBundleIdx int
firstTxFound = false
)
// 1. locate the first included tx of the bundle
for bundleIdx, tx := range b {
Expand All @@ -204,11 +205,22 @@ func checkBundlesAtomicity(
return NewErrBundleTxReverted(bundleHash, tx.hash, bundleIdx)
}

// optional txs can be outside the bundle, so we don't use them to determine ordering of the bundle
if tx.canRevert {
continue
}

firstTxBlockIdx = txInclusion.index
firstTxBundleIdx = bundleIdx
firstTxFound = true
break
}

// none of the txs from the bundle are included
if !firstTxFound {
continue
}

currentBlockTx := firstTxBlockIdx + 1
// locate other txs in the bundle
for idx, tx := range b[firstTxBundleIdx+1:] {
Expand All @@ -226,16 +238,21 @@ func checkBundlesAtomicity(
}
}

if txInclusion.reverted && !tx.canRevert {
return NewErrBundleTxReverted(bundleHash, tx.hash, bundleIdx)
}

// we don't do position check for optional txs
if tx.canRevert {
continue
}

// we allow gaps between txs in the bundle,
// but txs must be in the right order
if txInclusion.index < currentBlockTx {
return NewErrBundleTxWrongPlace(bundleHash, tx.hash, bundleIdx, txInclusion.index, currentBlockTx)
}

if txInclusion.reverted && !tx.canRevert {
return NewErrBundleTxReverted(bundleHash, tx.hash, bundleIdx)
}

currentBlockTx = txInclusion.index + 1
}
}
Expand Down
104 changes: 103 additions & 1 deletion miner/verify_bundles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ func TestVerifyBundlesAtomicity(t *testing.T) {
expectedErr error
}{
// Success cases
{
name: "Simple bundle with 1 tx included",
includedBundles: map[common.Hash][]bundleTxData{
common.HexToHash("0xb1"): {
{hash: common.HexToHash("0xb11"), canRevert: false},
},
},
includedTxDataByHash: map[common.Hash]includedTxData{
common.HexToHash("0xb11"): {hash: common.HexToHash("0xb11"), index: 0, reverted: false},
},
privateTxData: nil,
mempoolTxHashes: nil,
expectedErr: nil,
},
{
name: "Simple bundle included",
includedBundles: map[common.Hash][]bundleTxData{
Expand Down Expand Up @@ -120,6 +134,24 @@ func TestVerifyBundlesAtomicity(t *testing.T) {
privateTxData: nil,
expectedErr: nil,
},
{
name: "Bundle marked included but none of the txs are included (all optional)",
includedBundles: map[common.Hash][]bundleTxData{
common.HexToHash("0xb1"): {
{hash: common.HexToHash("0xb11"), canRevert: true},
{hash: common.HexToHash("0xb12"), canRevert: true},
{hash: common.HexToHash("0xb13"), canRevert: true},
},
},
includedTxDataByHash: map[common.Hash]includedTxData{
common.HexToHash("0xc1"): {hash: common.HexToHash("0xc1"), index: 0, reverted: false},
},
mempoolTxHashes: map[common.Hash]struct{}{
common.HexToHash("0xc1"): {},
},
privateTxData: nil,
expectedErr: nil,
},
{
name: "Simple bundle included with all revertible tx, last of them is included as success",
includedBundles: map[common.Hash][]bundleTxData{
Expand Down Expand Up @@ -185,6 +217,76 @@ func TestVerifyBundlesAtomicity(t *testing.T) {
},
expectedErr: nil,
},
{
name: "Two bundles included, one have optional tx in the middle that gets included as part of other bundle",
includedBundles: map[common.Hash][]bundleTxData{
common.HexToHash("0xb1"): {
{hash: common.HexToHash("0xb00"), canRevert: true},
{hash: common.HexToHash("0xb12"), canRevert: false},
},
common.HexToHash("0xb2"): {
{hash: common.HexToHash("0xb21"), canRevert: false},
{hash: common.HexToHash("0xb00"), canRevert: true},
{hash: common.HexToHash("0xb22"), canRevert: false},
},
},
includedTxDataByHash: map[common.Hash]includedTxData{
common.HexToHash("0xb00"): {hash: common.HexToHash("0xb00"), index: 0, reverted: false},
common.HexToHash("0xb12"): {hash: common.HexToHash("0xb12"), index: 1, reverted: false},
common.HexToHash("0xc1"): {hash: common.HexToHash("0xc1"), index: 2, reverted: true},
common.HexToHash("0xb21"): {hash: common.HexToHash("0xb21"), index: 3, reverted: false},
common.HexToHash("0xb22"): {hash: common.HexToHash("0xb22"), index: 4, reverted: false},
},
privateTxData: nil,
mempoolTxHashes: map[common.Hash]struct{}{
common.HexToHash("0xc1"): {},
},
expectedErr: nil,
},
{
name: "Optional tx in the middle of the bundle was included after the bundle as part of mempool",
includedBundles: map[common.Hash][]bundleTxData{
common.HexToHash("0xb1"): {
{hash: common.HexToHash("0xb11"), canRevert: false},
{hash: common.HexToHash("0xb00"), canRevert: true},
{hash: common.HexToHash("0xb12"), canRevert: false},
},
},
includedTxDataByHash: map[common.Hash]includedTxData{
common.HexToHash("0xb11"): {hash: common.HexToHash("0xb11"), index: 0, reverted: false},
common.HexToHash("0xb12"): {hash: common.HexToHash("0xb12"), index: 1, reverted: false},
common.HexToHash("0xc1"): {hash: common.HexToHash("0xc1"), index: 2, reverted: true},
common.HexToHash("0xb00"): {hash: common.HexToHash("0xb00"), index: 3, reverted: false},
},
privateTxData: nil,
mempoolTxHashes: map[common.Hash]struct{}{
common.HexToHash("0xc1"): {},
common.HexToHash("0xb00"): {},
},
expectedErr: nil,
},
{
name: "Optional tx in the middle of the bundle was included before the bundle as part of mempool",
includedBundles: map[common.Hash][]bundleTxData{
common.HexToHash("0xb1"): {
{hash: common.HexToHash("0xb11"), canRevert: false},
{hash: common.HexToHash("0xb00"), canRevert: true},
{hash: common.HexToHash("0xb12"), canRevert: false},
},
},
includedTxDataByHash: map[common.Hash]includedTxData{
common.HexToHash("0xb00"): {hash: common.HexToHash("0xb00"), index: 0, reverted: false},
common.HexToHash("0xb11"): {hash: common.HexToHash("0xb11"), index: 1, reverted: false},
common.HexToHash("0xb12"): {hash: common.HexToHash("0xb12"), index: 2, reverted: false},
common.HexToHash("0xc1"): {hash: common.HexToHash("0xc1"), index: 3, reverted: true},
},
privateTxData: nil,
mempoolTxHashes: map[common.Hash]struct{}{
common.HexToHash("0xc1"): {},
common.HexToHash("0xb00"): {},
},
expectedErr: nil,
},
{
name: "Private tx from overlapping included bundle included",
includedBundles: map[common.Hash][]bundleTxData{
Expand Down Expand Up @@ -423,7 +525,7 @@ func TestVerifyBundlesAtomicity(t *testing.T) {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Equal(t, err, test.expectedErr)
require.Equal(t, test.expectedErr, err)
}
})
}
Expand Down