github.com/ethereum-optimism/optimism@v1.7.2/op-node/rollup/derive/payloads_queue_test.go (about) 1 package derive 2 3 import ( 4 "container/heap" 5 "testing" 6 7 "github.com/ethereum/go-ethereum/common" 8 "github.com/ethereum/go-ethereum/log" 9 "github.com/stretchr/testify/require" 10 11 "github.com/ethereum-optimism/optimism/op-service/eth" 12 "github.com/ethereum-optimism/optimism/op-service/testlog" 13 ) 14 15 func TestPayloadsByNumber(t *testing.T) { 16 p := payloadsByNumber{} 17 mk := func(i uint64) payloadAndSize { 18 return payloadAndSize{ 19 envelope: ð.ExecutionPayloadEnvelope{ 20 ExecutionPayload: ð.ExecutionPayload{ 21 BlockNumber: eth.Uint64Quantity(i), 22 }, 23 }, 24 } 25 } 26 // add payload A, check it was added 27 a := mk(123) 28 heap.Push(&p, a) 29 require.Equal(t, p.Len(), 1) 30 require.Equal(t, p[0], a) 31 32 // add payload B, check it was added in top-priority spot 33 b := mk(100) 34 heap.Push(&p, b) 35 require.Equal(t, p.Len(), 2) 36 require.Equal(t, p[0], b) 37 38 // add payload C, check it did not get first like B, since block num is higher 39 c := mk(150) 40 heap.Push(&p, c) 41 require.Equal(t, p.Len(), 3) 42 require.Equal(t, p[0], b) // still b 43 44 // pop b 45 heap.Pop(&p) 46 require.Equal(t, p.Len(), 2) 47 require.Equal(t, p[0], a) 48 49 // pop a 50 heap.Pop(&p) 51 require.Equal(t, p.Len(), 1) 52 require.Equal(t, p[0], c) 53 54 // pop c 55 heap.Pop(&p) 56 require.Equal(t, p.Len(), 0) 57 58 // duplicate entry 59 heap.Push(&p, b) 60 require.Equal(t, p.Len(), 1) 61 heap.Push(&p, b) 62 require.Equal(t, p.Len(), 2) 63 heap.Pop(&p) 64 require.Equal(t, p.Len(), 1) 65 } 66 67 func TestPayloadMemSize(t *testing.T) { 68 require.Equal(t, payloadMemFixedCost, payloadMemSize(nil), "nil is same fixed cost") 69 require.Equal(t, payloadMemFixedCost, payloadMemSize(ð.ExecutionPayloadEnvelope{ExecutionPayload: ð.ExecutionPayload{}}), "empty payload fixed cost") 70 require.Equal(t, payloadMemFixedCost+payloadTxMemOverhead, payloadMemSize(ð.ExecutionPayloadEnvelope{ExecutionPayload: ð.ExecutionPayload{Transactions: []eth.Data{nil}}}), "nil tx counts") 71 require.Equal(t, payloadMemFixedCost+payloadTxMemOverhead, payloadMemSize(ð.ExecutionPayloadEnvelope{ExecutionPayload: ð.ExecutionPayload{Transactions: []eth.Data{make([]byte, 0)}}}), "empty tx counts") 72 require.Equal(t, payloadMemFixedCost+4*payloadTxMemOverhead+42+1337+0+1, 73 payloadMemSize(ð.ExecutionPayloadEnvelope{ExecutionPayload: ð.ExecutionPayload{Transactions: []eth.Data{ 74 make([]byte, 42), 75 make([]byte, 1337), 76 make([]byte, 0), 77 make([]byte, 1), 78 }}}), "mixed txs") 79 } 80 81 func envelope(payload *eth.ExecutionPayload) *eth.ExecutionPayloadEnvelope { 82 return ð.ExecutionPayloadEnvelope{ExecutionPayload: payload} 83 } 84 85 func TestPayloadsQueue(t *testing.T) { 86 pq := NewPayloadsQueue(testlog.Logger(t, log.LvlInfo), payloadMemFixedCost*3, payloadMemSize) 87 require.Equal(t, 0, pq.Len()) 88 require.Nil(t, pq.Peek()) 89 require.Nil(t, pq.Pop()) 90 91 a := envelope(ð.ExecutionPayload{BlockNumber: 3, BlockHash: common.Hash{3}}) 92 b := envelope(ð.ExecutionPayload{BlockNumber: 4, BlockHash: common.Hash{4}}) 93 c := envelope(ð.ExecutionPayload{BlockNumber: 5, BlockHash: common.Hash{5}}) 94 d := envelope(ð.ExecutionPayload{BlockNumber: 6, BlockHash: common.Hash{6}}) 95 bAlt := envelope(ð.ExecutionPayload{BlockNumber: 4, BlockHash: common.Hash{0xff}}) 96 bDup := envelope(ð.ExecutionPayload{BlockNumber: 4, BlockHash: common.Hash{4}}) 97 98 require.NoError(t, pq.Push(b)) 99 require.Equal(t, pq.Len(), 1) 100 require.Equal(t, pq.Peek(), b) 101 102 require.Error(t, pq.Push(nil), "cannot add nil payloads") 103 104 require.NoError(t, pq.Push(c)) 105 require.Equal(t, pq.Len(), 2) 106 require.Equal(t, pq.MemSize(), 2*payloadMemFixedCost) 107 require.Equal(t, pq.Peek(), b, "expecting b to still be the lowest number payload") 108 109 require.NoError(t, pq.Push(a)) 110 require.Equal(t, pq.Len(), 3) 111 require.Equal(t, pq.MemSize(), 3*payloadMemFixedCost) 112 require.Equal(t, pq.Peek(), a, "expecting a to be new lowest number") 113 114 require.Equal(t, pq.Pop(), a) 115 require.Equal(t, pq.Len(), 2, "expecting to pop the lowest") 116 117 require.Equal(t, pq.Peek(), b, "expecting b to be lowest, compared to c") 118 119 require.Equal(t, pq.Pop(), b) 120 require.Equal(t, pq.Len(), 1) 121 require.Equal(t, pq.MemSize(), payloadMemFixedCost) 122 123 require.Equal(t, pq.Pop(), c) 124 require.Equal(t, pq.Len(), 0, "expecting no items to remain") 125 126 e := envelope(ð.ExecutionPayload{BlockNumber: 5, Transactions: []eth.Data{make([]byte, payloadMemFixedCost*3+1)}}) 127 require.Error(t, pq.Push(e), "cannot add payloads that are too large") 128 129 require.NoError(t, pq.Push(b)) 130 require.Equal(t, pq.Len(), 1, "expecting b") 131 require.Equal(t, pq.Peek(), b) 132 require.NoError(t, pq.Push(c)) 133 require.Equal(t, pq.Len(), 2, "expecting b, c") 134 require.Equal(t, pq.Peek(), b) 135 require.NoError(t, pq.Push(a)) 136 require.Equal(t, pq.Len(), 3, "expecting a, b, c") 137 require.Equal(t, pq.Peek(), a) 138 139 // No duplicates allowed 140 require.Error(t, pq.Push(bDup)) 141 // But reorg data allowed 142 require.NoError(t, pq.Push(bAlt)) 143 144 require.NoError(t, pq.Push(d)) 145 require.Equal(t, pq.Len(), 3) 146 require.Equal(t, pq.Peek(), b, "expecting b, c, d") 147 require.NotContainsf(t, pq.pq[:], a, "a should be dropped after 3 items already exist under max size constraint") 148 }