code.vegaprotocol.io/vega@v0.79.0/core/pow/multiple_config_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package pow 17 18 import ( 19 "context" 20 "testing" 21 22 "code.vegaprotocol.io/vega/core/blockchain/abci" 23 "code.vegaprotocol.io/vega/libs/crypto" 24 "code.vegaprotocol.io/vega/libs/num" 25 "code.vegaprotocol.io/vega/logging" 26 27 "github.com/stretchr/testify/require" 28 ) 29 30 func TestConfigurationHistory(t *testing.T) { 31 e := New(logging.NewTestLogger(), NewDefaultConfig()) 32 33 e.BeginBlock(1, crypto.RandomHash(), []abci.Tx{}) 34 require.Equal(t, 0, len(e.activeParams)) 35 require.Equal(t, 0, len(e.activeStates)) 36 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(1)) 37 require.Equal(t, 1, len(e.activeParams)) 38 require.Equal(t, 1, len(e.activeStates)) 39 require.Equal(t, uint64(1), e.activeParams[0].fromBlock) 40 require.Nil(t, e.activeParams[0].untilBlock) 41 42 e.BeginBlock(2, crypto.RandomHash(), []abci.Tx{}) 43 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(5)) 44 require.Equal(t, 2, len(e.activeParams)) 45 require.Equal(t, 2, len(e.activeStates)) 46 require.Equal(t, uint64(1), e.activeParams[0].fromBlock) 47 require.Equal(t, uint64(2), *e.activeParams[0].untilBlock) 48 require.Equal(t, uint64(3), e.activeParams[1].fromBlock) 49 require.Nil(t, e.activeParams[1].untilBlock) 50 51 // we're in block 2, we expect difficulty to change in block 3 52 require.Equal(t, uint32(1), e.SpamPoWDifficulty()) 53 e.BeginBlock(3, crypto.RandomHash(), []abci.Tx{}) 54 require.Equal(t, uint32(5), e.SpamPoWDifficulty()) 55 } 56 57 func TestSpamPoWNumberOfPastBlocksChange(t *testing.T) { 58 e := New(logging.NewTestLogger(), NewDefaultConfig()) 59 e.BeginBlock(1, crypto.RandomHash(), []abci.Tx{}) 60 e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(10)) 61 62 // it's the first configuration so it's starting from this block rather than next 63 require.Equal(t, uint32(10), e.SpamPoWNumberOfPastBlocks()) 64 e.BeginBlock(2, crypto.RandomHash(), []abci.Tx{}) 65 e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(100)) 66 require.Equal(t, uint32(10), e.SpamPoWNumberOfPastBlocks()) 67 e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(110)) 68 require.Equal(t, uint32(10), e.SpamPoWNumberOfPastBlocks()) 69 e.BeginBlock(3, crypto.RandomHash(), []abci.Tx{}) 70 require.Equal(t, uint32(110), e.SpamPoWNumberOfPastBlocks()) 71 } 72 73 func TestSpamPoWDifficultyChange(t *testing.T) { 74 e := New(logging.NewTestLogger(), NewDefaultConfig()) 75 e.BeginBlock(1, crypto.RandomHash(), []abci.Tx{}) 76 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(10)) 77 78 // it's the first configuration so it's starting from this block rather than next 79 require.Equal(t, uint32(10), e.SpamPoWDifficulty()) 80 e.BeginBlock(2, crypto.RandomHash(), []abci.Tx{}) 81 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(100)) 82 require.Equal(t, uint32(10), e.SpamPoWDifficulty()) 83 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(110)) 84 require.Equal(t, uint32(10), e.SpamPoWDifficulty()) 85 e.BeginBlock(3, crypto.RandomHash(), []abci.Tx{}) 86 require.Equal(t, uint32(110), e.SpamPoWDifficulty()) 87 } 88 89 func TestSpamPoWHashChange(t *testing.T) { 90 e := New(logging.NewTestLogger(), NewDefaultConfig()) 91 e.BeginBlock(1, crypto.RandomHash(), []abci.Tx{}) 92 e.UpdateSpamPoWHashFunction(context.Background(), "f1") 93 94 // it's the first configuration so it's starting from this block rather than next 95 require.Equal(t, "f1", e.SpamPoWHashFunction()) 96 e.BeginBlock(2, crypto.RandomHash(), []abci.Tx{}) 97 e.UpdateSpamPoWHashFunction(context.Background(), "f2") 98 require.Equal(t, "f1", e.SpamPoWHashFunction()) 99 e.UpdateSpamPoWHashFunction(context.Background(), "f3") 100 require.Equal(t, "f1", e.SpamPoWHashFunction()) 101 e.BeginBlock(3, crypto.RandomHash(), []abci.Tx{}) 102 require.Equal(t, "f3", e.SpamPoWHashFunction()) 103 } 104 105 func TestSpamPoWNumberOfTxPerBlockChange(t *testing.T) { 106 e := New(logging.NewTestLogger(), NewDefaultConfig()) 107 e.BeginBlock(1, crypto.RandomHash(), []abci.Tx{}) 108 e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(10)) 109 110 // it's the first configuration so it's starting from this block rather than next 111 require.Equal(t, uint32(10), e.SpamPoWNumberOfTxPerBlock()) 112 e.BeginBlock(2, crypto.RandomHash(), []abci.Tx{}) 113 e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(100)) 114 require.Equal(t, uint32(10), e.SpamPoWNumberOfTxPerBlock()) 115 e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(110)) 116 require.Equal(t, uint32(10), e.SpamPoWNumberOfTxPerBlock()) 117 e.BeginBlock(3, crypto.RandomHash(), []abci.Tx{}) 118 require.Equal(t, uint32(110), e.SpamPoWNumberOfTxPerBlock()) 119 } 120 121 func TestSpamPoWIncreasingDifficultyChange(t *testing.T) { 122 e := New(logging.NewTestLogger(), NewDefaultConfig()) 123 e.BeginBlock(1, crypto.RandomHash(), []abci.Tx{}) 124 e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(1)) 125 126 // it's the first configuration so it's starting from this block rather than next 127 require.Equal(t, true, e.SpamPoWIncreasingDifficulty()) 128 e.BeginBlock(2, crypto.RandomHash(), []abci.Tx{}) 129 e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(1)) 130 require.Equal(t, true, e.SpamPoWIncreasingDifficulty()) 131 e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(0)) 132 require.Equal(t, true, e.SpamPoWIncreasingDifficulty()) 133 e.BeginBlock(3, crypto.RandomHash(), []abci.Tx{}) 134 require.Equal(t, false, e.SpamPoWIncreasingDifficulty()) 135 } 136 137 func TestBlockData(t *testing.T) { 138 e := New(logging.NewTestLogger(), NewDefaultConfig()) 139 blockHash := crypto.RandomHash() 140 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(5)) 141 e.BeginBlock(1, blockHash, []abci.Tx{}) 142 143 height, hash := e.BlockData() 144 require.Equal(t, uint64(1), height) 145 require.Equal(t, blockHash, hash) 146 147 blockHash = crypto.RandomHash() 148 e.BeginBlock(2, blockHash, []abci.Tx{}) 149 height, hash = e.BlockData() 150 require.Equal(t, uint64(2), height) 151 require.Equal(t, blockHash, hash) 152 } 153 154 func TestFindParamsForBlockHeight(t *testing.T) { 155 e := New(logging.NewTestLogger(), NewDefaultConfig()) 156 e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(100)) 157 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(20)) 158 e.UpdateSpamPoWHashFunction(context.Background(), "sha3") 159 e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(1)) 160 e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(1)) 161 162 e.BeginBlock(9, crypto.RandomHash(), []abci.Tx{}) 163 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(21)) 164 e.BeginBlock(19, crypto.RandomHash(), []abci.Tx{}) 165 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(22)) 166 e.BeginBlock(29, crypto.RandomHash(), []abci.Tx{}) 167 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(23)) 168 169 require.Equal(t, uint(20), e.activeParams[e.findParamsForBlockHeight(1)].spamPoWDifficulty) 170 require.Equal(t, uint(20), e.activeParams[e.findParamsForBlockHeight(9)].spamPoWDifficulty) 171 require.Equal(t, uint(21), e.activeParams[e.findParamsForBlockHeight(10)].spamPoWDifficulty) 172 require.Equal(t, uint(21), e.activeParams[e.findParamsForBlockHeight(19)].spamPoWDifficulty) 173 require.Equal(t, uint(22), e.activeParams[e.findParamsForBlockHeight(20)].spamPoWDifficulty) 174 require.Equal(t, uint(22), e.activeParams[e.findParamsForBlockHeight(29)].spamPoWDifficulty) 175 require.Equal(t, uint(23), e.activeParams[e.findParamsForBlockHeight(30)].spamPoWDifficulty) 176 require.Equal(t, uint(23), e.activeParams[e.findParamsForBlockHeight(100)].spamPoWDifficulty) 177 } 178 179 // func TestVerifyWithMultipleConfigs(t *testing.T) { 180 // e := New(logging.NewTestLogger(), NewDefaultConfig()) 181 // e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(100)) 182 // e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(20)) 183 // e.UpdateSpamPoWHashFunction(context.Background(), "sha3_24_rounds") 184 // e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(1)) 185 // e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(0)) 186 187 // block9Hash := "2E7A16D9EF690F0D2BEED115FBA13BA2AAA16C8F971910AD88C72B9DB010C7D4" 188 // e.BeginBlock(9, block9Hash) 189 // e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(21)) 190 // e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(50)) 191 // e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(5)) 192 // e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(1)) 193 194 // e.EndOfBlock() 195 // e.BeginBlock(19, crypto.RandomHash()) 196 // e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(22)) 197 // e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(80)) 198 // e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(1)) 199 // e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(1)) 200 201 // e.EndOfBlock() 202 // block29Hash := "8890702af457ddcda01fba579a126adcecae954781500acb546fef9c8087a239" 203 // e.BeginBlock(29, block29Hash) 204 // e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(1)) 205 // e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(70)) 206 // e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(2)) 207 // e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(0)) 208 // e.EndOfBlock() 209 210 // block30Hash := "377EEAC9847D751A4FAFD3F2896E99C1A03363EBDA3036C33940CFE578E196D1" 211 // e.BeginBlock(30, block30Hash) 212 213 // // now we're in block 90 214 // e.BeginBlock(90, "792ca202b84226c739f9923046a0f4e7b5ff9e6f1b5636d8e26a8e2c5dec70ac") 215 216 // // transactions sent from block height < 10 have past blocks of 100, difficulty of 20 and allow 1 transaction per block with no increased difficulty 217 // tx9_1 := &testTx{txID: "1", blockHeight: 9, party: "party", powTxID: "DFE522E234D67E6AE3F017859F898E576B3928EA57310B765398615A0D3FDE2F", powNonce: 424517} 218 // err := e.DeliverTx(tx9_1) 219 // require.NoError(t, err) 220 221 // // doesn't really matter what the pow data is because in block 19 the parameters allowed only 50 blocks behind meaning in block 90 the transaction should be rejected as too old 222 // tx19 := &testTx{txID: "2", blockHeight: 19, party: "party", powTxID: "5B87F9DFA41DABE84A11CA78D9FE11DA8FC2AA926004CA66454A7AF0A206480D", powNonce: 4095356} 223 // err = e.DeliverTx(tx19) 224 // require.Equal(t, "unknown block height for tx:32, command:Amend Order, party:party", err.Error()) 225 226 // // in block 29 we're allowed to submit 1 transactions with difficulty starting at 22 and increased difficulty 227 // tx29_1 := &testTx{txID: "3", blockHeight: 29, party: "party", powTxID: "74030ee7dc931be9d9cc5f2c9d44ac174b4144b377ef07a7bb1781856921dd43", powNonce: 1903233} 228 // tx29_2 := &testTx{txID: "4", blockHeight: 29, party: "party", powTxID: "94A9CB1532011081B013CCD8E6AAA832CAB1CBA603F0C5A093B14C4961E5E7F0", powNonce: 7914217} 229 // err = e.DeliverTx(tx29_1) 230 // require.NoError(t, err) 231 // err = e.DeliverTx(tx29_2) 232 // require.NoError(t, err) 233 234 // // finally we have a transaction sent in block 30 which allows for 2 transactions with no increased difficulty 235 // tx30_1 := &testTx{txID: "5", blockHeight: 30, party: "party", powTxID: "2A1319636230740888C968E4E7610D6DE820E644EEC3C08AA5322A0A022014BD", powNonce: 380742} 236 // err = e.DeliverTx(tx30_1) 237 // require.NoError(t, err) 238 239 // tx30_2 := &testTx{txID: "6", blockHeight: 30, party: "party", powTxID: "2E7A16D9EF690F0D2BEED115FBA13BA2AAA16C8F971910AD88C72B9DB010C7D4", powNonce: 1296835} 240 // err = e.DeliverTx(tx30_2) 241 // require.NoError(t, err) 242 // tx30_3 := &testTx{txID: "7", blockHeight: 30, party: "party", powTxID: "5B0E1EB96CCAC120E6D824A5F4C4007EABC59573B861BD84B1EF09DFB376DC84", powNonce: 388948} 243 // err = e.DeliverTx(tx30_3) 244 // // the third transaction would be rejected and ban the party 245 // require.Equal(t, "too many transactions per block", err.Error()) 246 247 // // now move on to the next block and the party should be banned 248 // e.BeginBlock(91, crypto.RandomHash()) 249 // tx90 := &testTx{txID: "7", blockHeight: 90, party: "party", powTxID: "3b8399cdffee2686d75d1a96d22cd49cd11f62c93da20e72239895bfdaf4b772", powNonce: 0} 250 // err = e.DeliverTx(tx90) 251 // require.Equal(t, "party is banned from sending transactions", err.Error()) 252 // } 253 254 func TestEndOfBlockCleanup(t *testing.T) { 255 e := New(logging.NewTestLogger(), NewDefaultConfig()) 256 e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(100)) 257 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(20)) 258 e.UpdateSpamPoWHashFunction(context.Background(), "sha3_24_rounds") 259 e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(1)) 260 e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(0)) 261 262 // the setting above is good for transactions from blocks 0 - 9+100 263 // that means at the end of block 109 it can be removed 264 265 e.BeginBlock(9, crypto.RandomHash(), []abci.Tx{}) 266 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(21)) 267 e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(50)) 268 e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(5)) 269 e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(1)) 270 271 // the setting above is good for transactions from blocks 10 - 19+50 272 // that means at the end of block 69 it can be removed 273 274 e.BeginBlock(19, crypto.RandomHash(), []abci.Tx{}) 275 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(22)) 276 e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(80)) 277 e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(1)) 278 e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(1)) 279 280 // the setting above is good for transactions from blocks 20 - 29+80 281 // that means at the end of block 109 it can be removed 282 283 e.BeginBlock(29, crypto.RandomHash(), []abci.Tx{}) 284 e.UpdateSpamPoWDifficulty(context.Background(), num.NewUint(1)) 285 e.UpdateSpamPoWNumberOfPastBlocks(context.Background(), num.NewUint(70)) 286 e.UpdateSpamPoWNumberOfTxPerBlock(context.Background(), num.NewUint(2)) 287 e.UpdateSpamPoWIncreasingDifficulty(context.Background(), num.NewUint(0)) 288 289 // the setting above is good for transactions from blocks 30 - 290 291 e.BeginBlock(30, crypto.RandomHash(), []abci.Tx{}) 292 293 require.Equal(t, 4, len(e.activeParams)) 294 require.Equal(t, 4, len(e.activeStates)) 295 296 e.BeginBlock(69, crypto.RandomHash(), []abci.Tx{}) 297 298 require.Equal(t, 3, len(e.activeParams)) 299 require.Equal(t, 3, len(e.activeStates)) 300 301 e.BeginBlock(109, crypto.RandomHash(), []abci.Tx{}) 302 303 require.Equal(t, 1, len(e.activeParams)) 304 require.Equal(t, 1, len(e.activeStates)) 305 require.Equal(t, uint32(70), e.SpamPoWNumberOfPastBlocks()) 306 require.Equal(t, uint32(1), e.SpamPoWDifficulty()) 307 require.Equal(t, false, e.SpamPoWIncreasingDifficulty()) 308 require.Equal(t, uint32(2), e.SpamPoWNumberOfTxPerBlock()) 309 }