From bbb7252173b96ada5f48c200fbffcaf35656cb36 Mon Sep 17 00:00:00 2001 From: Nicholas Pettas Date: Wed, 28 Aug 2024 17:24:42 -0700 Subject: [PATCH] remove go-x1 evm --- evm/go-x1/.codacy.yml | 29 - evm/go-x1/.dockerignore | 1 - evm/go-x1/.editorconfig | 21 - evm/go-x1/.github/CODEOWNERS | 2 - .../.github/ISSUE_TEMPLATE/bug_report.md | 35 - .../.github/ISSUE_TEMPLATE/feature_request.md | 17 - evm/go-x1/.github/workflows/release_build.yml | 30 - evm/go-x1/.github/workflows/test_build.yml | 32 - evm/go-x1/.goreleaser.yml | 58 - evm/go-x1/.run/testnet.run.xml | 12 - evm/go-x1/.travis.yml | 43 - evm/go-x1/CODE_OF_CONDUCT.md | 46 - evm/go-x1/CONTRIBUTING.md | 112 - evm/go-x1/COPYING.LESSER | 166 - evm/go-x1/FUZZING.md | 34 - evm/go-x1/Makefile | 42 - evm/go-x1/PULL_REQUEST_TEMPLATE.md | 17 - evm/go-x1/README.md | 31 - evm/go-x1/_config.yml | 28 - evm/go-x1/appveyor.yml | 27 - evm/go-x1/cmd/cmdtest/test_cmd.go | 277 -- evm/go-x1/cmd/opera/launcher/accountcmd.go | 413 -- .../cmd/opera/launcher/accountcmd_test.go | 301 -- evm/go-x1/cmd/opera/launcher/chaincmd.go | 144 - evm/go-x1/cmd/opera/launcher/check.go | 67 - evm/go-x1/cmd/opera/launcher/config.go | 611 --- evm/go-x1/cmd/opera/launcher/config_custom.go | 79 - .../cmd/opera/launcher/config_custom_test.go | 74 - evm/go-x1/cmd/opera/launcher/consolecmd.go | 215 - .../cmd/opera/launcher/consolecmd_test.go | 147 - evm/go-x1/cmd/opera/launcher/db-transform.go | 349 -- evm/go-x1/cmd/opera/launcher/dbcmd.go | 175 - evm/go-x1/cmd/opera/launcher/defaults.go | 105 - evm/go-x1/cmd/opera/launcher/export.go | 155 - evm/go-x1/cmd/opera/launcher/fake.go | 51 - evm/go-x1/cmd/opera/launcher/fake_test.go | 118 - evm/go-x1/cmd/opera/launcher/fixdirty.go | 194 - evm/go-x1/cmd/opera/launcher/genesiscmd.go | 404 -- evm/go-x1/cmd/opera/launcher/import.go | 239 - evm/go-x1/cmd/opera/launcher/launcher.go | 478 -- .../cmd/opera/launcher/metrics/metrics.go | 78 - evm/go-x1/cmd/opera/launcher/misccmd.go | 59 - evm/go-x1/cmd/opera/launcher/params.go | 46 - evm/go-x1/cmd/opera/launcher/run_test.go | 124 - evm/go-x1/cmd/opera/launcher/snapshotcmd.go | 477 -- evm/go-x1/cmd/opera/launcher/testdata/dupes/1 | 1 - evm/go-x1/cmd/opera/launcher/testdata/dupes/2 | 1 - .../cmd/opera/launcher/testdata/dupes/foo | 1 - .../cmd/opera/launcher/testdata/empty.js | 1 - .../opera/launcher/testdata/guswallet.json | 6 - .../launcher/testdata/keystore/.hiddenfile | 1 - .../opera/launcher/testdata/keystore/README | 21 - ...--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 | 1 - .../cmd/opera/launcher/testdata/keystore/aaa | 1 - .../opera/launcher/testdata/keystore/empty | 0 .../fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e | 1 - .../opera/launcher/testdata/keystore/garbage | Bin 300 -> 0 bytes .../launcher/testdata/keystore/no-address | 1 - .../cmd/opera/launcher/testdata/keystore/zero | 1 - .../cmd/opera/launcher/testdata/keystore/zzz | 1 - .../cmd/opera/launcher/testdata/passwords.txt | 3 - .../launcher/testdata/wrong-passwords.txt | 3 - evm/go-x1/cmd/opera/launcher/testnet.go | 11 - .../cmd/opera/launcher/tracing/tracing.go | 47 - evm/go-x1/cmd/opera/launcher/usage.go | 163 - evm/go-x1/cmd/opera/launcher/validator.go | 67 - evm/go-x1/cmd/opera/launcher/validatorcmd.go | 160 - evm/go-x1/cmd/opera/launcher/valkeystore.go | 76 - evm/go-x1/cmd/opera/launcher/x1testnet.go | 17 - evm/go-x1/cmd/opera/main.go | 15 - evm/go-x1/debug/api.go | 236 - evm/go-x1/debug/flags.go | 273 -- evm/go-x1/debug/loudpanic.go | 28 - evm/go-x1/debug/loudpanic_fallback.go | 25 - evm/go-x1/debug/trace.go | 64 - evm/go-x1/debug/trace_fallback.go | 32 - evm/go-x1/demo/.gitignore | 2 - evm/go-x1/demo/README.md | 79 - evm/go-x1/demo/_params.sh | 36 - evm/go-x1/demo/clean.sh | 7 - evm/go-x1/demo/start.sh | 48 - evm/go-x1/demo/stop.sh | 3 - evm/go-x1/docker/Dockerfile.opera | 22 - evm/go-x1/ethapi/README.md | 1 - evm/go-x1/ethapi/abft_api.go | 75 - evm/go-x1/ethapi/addrlock.go | 53 - evm/go-x1/ethapi/api.go | 2159 --------- evm/go-x1/ethapi/backend.go | 190 - evm/go-x1/ethapi/dag_api.go | 81 - evm/go-x1/ethapi/transaction_args.go | 285 -- evm/go-x1/eventcheck/all.go | 43 - evm/go-x1/eventcheck/ban.go | 42 - .../eventcheck/basiccheck/basic_check.go | 306 -- evm/go-x1/eventcheck/bvallcheck/all_check.go | 34 - .../eventcheck/epochcheck/epoch_check.go | 133 - evm/go-x1/eventcheck/evallcheck/evallcheck.go | 34 - .../gaspowercheck/gas_power_check.go | 180 - evm/go-x1/eventcheck/heavycheck/adapters.go | 31 - evm/go-x1/eventcheck/heavycheck/config.go | 13 - .../eventcheck/heavycheck/heavy_check.go | 313 -- .../parentlesscheck/parentless_check.go | 29 - .../eventcheck/parentscheck/parents_check.go | 46 - evm/go-x1/evmcore/.gitignore | 12 - evm/go-x1/evmcore/apply_fake_genesis.go | 206 - evm/go-x1/evmcore/bench_test.go | 166 - evm/go-x1/evmcore/blocks.go | 24 - evm/go-x1/evmcore/chain_makers.go | 290 -- evm/go-x1/evmcore/dummy_block.go | 164 - evm/go-x1/evmcore/error.go | 87 - evm/go-x1/evmcore/evm.go | 113 - evm/go-x1/evmcore/gaspool.go | 54 - evm/go-x1/evmcore/helper_test.go | 86 - evm/go-x1/evmcore/notify.go | 48 - evm/go-x1/evmcore/state_prefetcher.go | 93 - evm/go-x1/evmcore/state_processor.go | 171 - evm/go-x1/evmcore/state_transition.go | 334 -- evm/go-x1/evmcore/tx_cacher.go | 105 - evm/go-x1/evmcore/tx_journal.go | 180 - evm/go-x1/evmcore/tx_list.go | 627 --- evm/go-x1/evmcore/tx_list_test.go | 70 - evm/go-x1/evmcore/tx_noncer.go | 79 - evm/go-x1/evmcore/tx_pool.go | 1887 -------- evm/go-x1/evmcore/tx_pool_test.go | 2567 ----------- evm/go-x1/evmcore/types.go | 51 - evm/go-x1/flags/helpers.go | 121 - evm/go-x1/ftmclient/dag_api.go | 91 - evm/go-x1/ftmclient/ethclient.go | 35 - evm/go-x1/go.mod | 112 - evm/go-x1/go.sum | 1078 ----- evm/go-x1/gossip/api.go | 37 - evm/go-x1/gossip/apply_genesis.go | 94 - evm/go-x1/gossip/basiccheck_test.go | 905 ---- .../blockproc/drivermodule/driver_txs.go | 241 - .../eventmodule/confirmed_events_processor.go | 68 - evm/go-x1/gossip/blockproc/evmmodule/evm.go | 129 - evm/go-x1/gossip/blockproc/interface.go | 56 - .../gossip/blockproc/sealmodule/sealer.go | 104 - .../gossip/blockproc/verwatcher/store.go | 31 - .../verwatcher/store_network_version.go | 62 - .../blockproc/verwatcher/version_watcher.go | 82 - evm/go-x1/gossip/c_block_callbacks.go | 641 --- evm/go-x1/gossip/c_block_callbacks_test.go | 67 - evm/go-x1/gossip/c_event_callbacks.go | 315 -- evm/go-x1/gossip/c_llr_callbacks.go | 293 -- evm/go-x1/gossip/c_llr_callbacks_test.go | 1702 ------- evm/go-x1/gossip/checker_helpers.go | 119 - evm/go-x1/gossip/common_test.go | 546 --- evm/go-x1/gossip/config.go | 299 -- evm/go-x1/gossip/contract/ballot/Ballot.go | 604 --- evm/go-x1/gossip/contract/ballot/Ballot.sol | 156 - evm/go-x1/gossip/contract/ballot/ballot.abi | 1 - evm/go-x1/gossip/contract/ballot/ballot.bin | 1 - evm/go-x1/gossip/contract/contract.go | 458 -- .../gossip/contract/driver100/contract.go | 1418 ------ .../gossip/contract/driverauth100/contract.go | 860 ---- .../gossip/contract/netinit100/contract.go | 225 - evm/go-x1/gossip/contract/sfc100/contract.go | 2146 --------- .../gossip/contract/sfclib100/contract.go | 4066 ----------------- evm/go-x1/gossip/contract/solc/.gitignore | 4 - evm/go-x1/gossip/discover.go | 68 - evm/go-x1/gossip/dummy_tx_pool.go | 169 - evm/go-x1/gossip/emitter/config.go | 106 - evm/go-x1/gossip/emitter/control.go | 140 - evm/go-x1/gossip/emitter/emitter.go | 464 -- evm/go-x1/gossip/emitter/emitter_llr.go | 125 - evm/go-x1/gossip/emitter/emitter_test.go | 118 - evm/go-x1/gossip/emitter/hooks.go | 144 - evm/go-x1/gossip/emitter/mock/world.go | 620 --- .../emitter/originatedtxs/txs_ring_buffer.go | 58 - evm/go-x1/gossip/emitter/parents.go | 55 - evm/go-x1/gossip/emitter/piecefuncs.go | 130 - evm/go-x1/gossip/emitter/prev_action_files.go | 91 - evm/go-x1/gossip/emitter/sync.go | 79 - evm/go-x1/gossip/emitter/txs.go | 174 - evm/go-x1/gossip/emitter/validators.go | 66 - evm/go-x1/gossip/emitter/world.go | 92 - evm/go-x1/gossip/emitter_world.go | 111 - evm/go-x1/gossip/enr_entry.go | 23 - evm/go-x1/gossip/eth_state_adapter.go | 36 - evm/go-x1/gossip/ethapi_backend.go | 543 --- evm/go-x1/gossip/evm_state_reader.go | 143 - evm/go-x1/gossip/evm_test.go | 104 - evm/go-x1/gossip/evmstore/apply_genesis.go | 48 - evm/go-x1/gossip/evmstore/config.go | 64 - evm/go-x1/gossip/evmstore/evmpruner/bloom.go | 133 - evm/go-x1/gossip/evmstore/evmpruner/exact.go | 48 - evm/go-x1/gossip/evmstore/evmpruner/pruner.go | 437 -- evm/go-x1/gossip/evmstore/store.go | 304 -- .../gossip/evmstore/store_block_cache.go | 25 - evm/go-x1/gossip/evmstore/store_receipts.go | 95 - .../gossip/evmstore/store_receipts_test.go | 105 - evm/go-x1/gossip/evmstore/store_test.go | 17 - evm/go-x1/gossip/evmstore/store_tx.go | 59 - .../gossip/evmstore/store_tx_position.go | 45 - evm/go-x1/gossip/evmstore/utils.go | 210 - evm/go-x1/gossip/execqueue.go | 88 - evm/go-x1/gossip/filters/api.go | 600 --- evm/go-x1/gossip/filters/api_test.go | 185 - evm/go-x1/gossip/filters/filter.go | 292 -- evm/go-x1/gossip/filters/filter_system.go | 398 -- .../gossip/filters/filter_system_test.go | 460 -- evm/go-x1/gossip/filters/filter_test.go | 269 -- evm/go-x1/gossip/gasprice/constructive.go | 82 - evm/go-x1/gossip/gasprice/gasprice.go | 217 - evm/go-x1/gossip/gasprice/gasprice_test.go | 325 -- evm/go-x1/gossip/gasprice/reactive.go | 260 -- evm/go-x1/gossip/gpo_backend.go | 96 - evm/go-x1/gossip/handler.go | 1538 ------- evm/go-x1/gossip/handler_fuzz.go | 165 - evm/go-x1/gossip/handler_snap.go | 69 - evm/go-x1/gossip/heavycheck_test.go | 832 ---- evm/go-x1/gossip/mps_test.go | 842 ---- evm/go-x1/gossip/peer.go | 589 --- evm/go-x1/gossip/peerset.go | 264 -- evm/go-x1/gossip/proclogger/dag_logger.go | 46 - evm/go-x1/gossip/proclogger/llr_logger.go | 178 - evm/go-x1/gossip/protocol.go | 163 - .../blockrecords/brprocessor/config.go | 29 - .../blockrecords/brprocessor/processor.go | 95 - .../brstream/brstreamleecher/config.go | 42 - .../brstream/brstreamleecher/leecher.go | 218 - .../brstream/brstreamseeder/config.go | 19 - .../brstream/brstreamseeder/seeder.go | 82 - .../protocols/blockrecords/brstream/types.go | 78 - .../blockvotes/bvprocessor/config.go | 29 - .../blockvotes/bvprocessor/processor.go | 155 - .../bvstream/bvstreamleecher/config.go | 42 - .../bvstream/bvstreamleecher/leecher.go | 210 - .../bvstream/bvstreamseeder/config.go | 19 - .../bvstream/bvstreamseeder/seeder.go | 86 - .../protocols/blockvotes/bvstream/types.go | 77 - .../dag/dagstream/dagstreamleecher/config.go | 42 - .../dag/dagstream/dagstreamleecher/leecher.go | 227 - .../dagstreamleecher/leecher_test.go | 94 - .../dag/dagstream/dagstreamseeder/config.go | 19 - .../dag/dagstream/dagstreamseeder/seeder.go | 95 - .../gossip/protocols/dag/dagstream/types.go | 82 - .../epochpacks/epprocessor/config.go | 29 - .../epochpacks/epprocessor/processor.go | 167 - .../epstream/epstreamleecher/config.go | 42 - .../epstream/epstreamleecher/leecher.go | 201 - .../epstream/epstreamseeder/config.go | 19 - .../epstream/epstreamseeder/seeder.go | 82 - .../protocols/epochpacks/epstream/types.go | 78 - evm/go-x1/gossip/protocols/snap/api.go | 168 - evm/go-x1/gossip/protocols/snap/events.go | 25 - .../snap/snapstream/snapleecher/leecher.go | 131 - .../snap/snapstream/snapleecher/peer.go | 315 -- .../snap/snapstream/snapleecher/statesync.go | 330 -- .../snap/snapstream/snapleecher/types.go | 41 - evm/go-x1/gossip/randselect.go | 153 - evm/go-x1/gossip/service.go | 512 --- evm/go-x1/gossip/sfc_test.go | 226 - evm/go-x1/gossip/store.go | 301 -- evm/go-x1/gossip/store_activation_heights.go | 27 - evm/go-x1/gossip/store_block.go | 223 - evm/go-x1/gossip/store_decided_state.go | 167 - evm/go-x1/gossip/store_epoch.go | 117 - evm/go-x1/gossip/store_event.go | 206 - evm/go-x1/gossip/store_heads.go | 108 - evm/go-x1/gossip/store_last_bv.go | 93 - evm/go-x1/gossip/store_last_ev.go | 93 - evm/go-x1/gossip/store_last_events.go | 118 - evm/go-x1/gossip/store_llr_block.go | 270 -- evm/go-x1/gossip/store_llr_epoch.go | 113 - evm/go-x1/gossip/store_llr_state.go | 43 - evm/go-x1/gossip/store_migration.go | 143 - evm/go-x1/gossip/sync.go | 296 -- evm/go-x1/gossip/tflusher.go | 47 - evm/go-x1/integration/assembly.go | 356 -- evm/go-x1/integration/bench_db_flush_test.go | 75 - evm/go-x1/integration/db.go | 182 - evm/go-x1/integration/diskusage.go | 43 - evm/go-x1/integration/diskusage_openbsd.go | 44 - evm/go-x1/integration/diskusage_windows.go | 38 - evm/go-x1/integration/legacy_migrate.go | 338 -- .../integration/makefakegenesis/genesis.go | 200 - evm/go-x1/integration/makegenesis/genesis.go | 261 -- .../integration/maketestnetgenesis/genesis.go | 173 - evm/go-x1/integration/metric.go | 176 - evm/go-x1/integration/metric_test.go | 26 - evm/go-x1/integration/presets.go | 549 --- evm/go-x1/integration/routing.go | 65 - evm/go-x1/integration/status.go | 23 - evm/go-x1/inter/block.go | 40 - evm/go-x1/inter/drivertype/driver_type.go | 27 - evm/go-x1/inter/event.go | 344 -- evm/go-x1/inter/event_serializer.go | 558 --- evm/go-x1/inter/event_serializer_test.go | 406 -- evm/go-x1/inter/event_test.go | 58 - evm/go-x1/inter/events.go | 121 - evm/go-x1/inter/gas_power_left.go | 57 - evm/go-x1/inter/gas_power_left_test.go | 19 - evm/go-x1/inter/iblockproc/decided_state.go | 154 - evm/go-x1/inter/iblockproc/legacy.go | 29 - evm/go-x1/inter/iblockproc/profiles.go | 63 - evm/go-x1/inter/ibr/inter_block_records.go | 48 - evm/go-x1/inter/iep/inter_epoch_packs.go | 11 - evm/go-x1/inter/ier/inter_epoch_records.go | 22 - evm/go-x1/inter/inter_llr.go | 94 - evm/go-x1/inter/inter_llr_test.go | 60 - evm/go-x1/inter/inter_mps.go | 55 - evm/go-x1/inter/signature.go | 18 - evm/go-x1/inter/time.go | 45 - evm/go-x1/inter/transaction_serializer.go | 166 - .../inter/transaction_serializer_test.go | 144 - evm/go-x1/inter/validatorpk/pubkey.go | 66 - evm/go-x1/inter/validatorpk/pubkey_test.go | 59 - evm/go-x1/logger/instance.go | 20 - evm/go-x1/logger/logger.go | 49 - evm/go-x1/logger/logrus.go | 30 - evm/go-x1/logger/periodic_log.go | 51 - evm/go-x1/logger/test_output.go | 21 - .../contracts/driver/driver_predeploy.go | 17 - .../driver/drivercall/driver_calls.go | 83 - .../contracts/driver/driverpos/positions.go | 24 - .../opera/contracts/driverauth/driverauth.go | 17 - .../contracts/emitterdriver/emitterdriver.go | 6 - .../opera/contracts/evmwriter/evm_writer.go | 202 - .../contracts/evmwriter/evm_writer_test.go | 18 - .../netinitcalls/network_initializer_calls.go | 25 - .../contracts/netinit/network_initializer.go | 17 - .../opera/contracts/sfc/sfc_predeploy.go | 17 - .../contracts/sfclib/sfclib_predeploy.go | 17 - evm/go-x1/opera/genesis/gpos/validators.go | 52 - evm/go-x1/opera/genesis/types.go | 67 - evm/go-x1/opera/genesisstore/disk.go | 167 - .../opera/genesisstore/filelog/filelog.go | 49 - .../genesisstore/fileshash/filehash_test.go | 220 - .../genesisstore/fileshash/reader_file.go | 210 - .../genesisstore/fileshash/reader_map.go | 25 - .../genesisstore/fileshash/write_file.go | 189 - .../genesisstore/readersmap/reader_map.go | 37 - evm/go-x1/opera/genesisstore/store.go | 47 - evm/go-x1/opera/genesisstore/store_genesis.go | 123 - evm/go-x1/opera/legacy_serialization.go | 175 - evm/go-x1/opera/marshal.go | 16 - evm/go-x1/opera/marshal_test.go | 122 - evm/go-x1/opera/rules.go | 335 -- evm/go-x1/sonar-project.properties | 9 - evm/go-x1/topicsdb/index.go | 141 - evm/go-x1/topicsdb/key.go | 82 - evm/go-x1/topicsdb/key_test.go | 19 - evm/go-x1/topicsdb/record.go | 62 - evm/go-x1/topicsdb/search_parallel.go | 121 - evm/go-x1/topicsdb/search_test.go | 52 - evm/go-x1/topicsdb/sync.go | 141 - evm/go-x1/topicsdb/thread_pool.go | 105 - evm/go-x1/topicsdb/topicsdb.go | 76 - evm/go-x1/topicsdb/topicsdb_test.go | 556 --- evm/go-x1/tracing/tx-tracing.go | 80 - .../utils/adapters/ethdb2kvdb/adapter.go | 49 - .../utils/adapters/kvdb2ethdb/adapter.go | 40 - evm/go-x1/utils/adapters/snap2kvdb/adapter.go | 50 - .../adapters/vecmt2dagidx/vecmt2lachesis.go | 54 - evm/go-x1/utils/bitmap/bitset.go | 29 - evm/go-x1/utils/bits/bits.go | 130 - evm/go-x1/utils/bits/bits_test.go | 147 - .../utils/concurrent/ValidatorBlocksSet.go | 19 - .../utils/concurrent/ValidatorEpochsSet.go | 19 - .../utils/concurrent/ValidatorEventsSet.go | 20 - evm/go-x1/utils/concurrent/events.go | 19 - evm/go-x1/utils/cser/binary.go | 96 - evm/go-x1/utils/cser/binary_test.go | 337 -- evm/go-x1/utils/cser/read_writer.go | 250 - evm/go-x1/utils/cser/read_writer_test.go | 97 - .../dbutil/asyncflushproducer/producer.go | 78 - .../utils/dbutil/asyncflushproducer/store.go | 14 - evm/go-x1/utils/dbutil/autocompact/store.go | 143 - .../utils/dbutil/autocompact/strategy.go | 137 - evm/go-x1/utils/dbutil/compactdb/compactdb.go | 99 - evm/go-x1/utils/dbutil/compactdb/keys.go | 96 - evm/go-x1/utils/dbutil/compactdb/keys_test.go | 104 - evm/go-x1/utils/dbutil/compactdb/log.go | 65 - evm/go-x1/utils/dbutil/dbcounter/dbcounter.go | 99 - evm/go-x1/utils/dbutil/itergc/iterator_gc.go | 64 - evm/go-x1/utils/dbutil/switchable/snapshot.go | 152 - .../utils/dbutil/switchable/snapshot_test.go | 152 - evm/go-x1/utils/dbutil/threads/counted.go | 63 - evm/go-x1/utils/dbutil/threads/pool.go | 77 - evm/go-x1/utils/dbutil/threads/pool_test.go | 47 - evm/go-x1/utils/devnullfile/devnull.go | 26 - evm/go-x1/utils/errlock/errlock.go | 74 - evm/go-x1/utils/eventid/eventid.go | 69 - evm/go-x1/utils/fast/buffer.go | 73 - evm/go-x1/utils/fast/buffer_test.go | 88 - evm/go-x1/utils/file.go | 54 - evm/go-x1/utils/iodb/io_db.go | 98 - evm/go-x1/utils/ioread/ioread.go | 17 - evm/go-x1/utils/memory/LICENSE | 29 - evm/go-x1/utils/memory/doc.go | 24 - evm/go-x1/utils/memory/memory_bsd.go | 20 - evm/go-x1/utils/memory/memory_darwin.go | 50 - evm/go-x1/utils/memory/memory_linux.go | 30 - evm/go-x1/utils/memory/memory_test.go | 12 - evm/go-x1/utils/memory/memory_windows.go | 61 - evm/go-x1/utils/memory/memsysctl.go | 22 - evm/go-x1/utils/memory/stub.go | 11 - evm/go-x1/utils/migration/id_store.go | 19 - evm/go-x1/utils/migration/kvdb_id_store.go | 41 - evm/go-x1/utils/migration/migration.go | 99 - evm/go-x1/utils/migration/migration_test.go | 105 - evm/go-x1/utils/nameof.go | 17 - evm/go-x1/utils/num_queue.go | 55 - evm/go-x1/utils/num_queue_test.go | 55 - evm/go-x1/utils/pretty_duration.go | 54 - evm/go-x1/utils/pretty_duration_test.go | 33 - evm/go-x1/utils/randat/rand_at.go | 26 - evm/go-x1/utils/rate/gauge.go | 80 - evm/go-x1/utils/rate/gauge_test.go | 39 - evm/go-x1/utils/rlpstore/rlpstore.go | 40 - evm/go-x1/utils/self-table.go | 13 - .../signers/gsignercache/global_cache.go | 32 - .../utils/signers/internaltx/internaltx.go | 23 - .../signers/internaltx/internaltx_test.go | 86 - evm/go-x1/utils/spin_lock.go | 37 - evm/go-x1/utils/to_ftm.go | 8 - evm/go-x1/utils/txtime/txtime.go | 49 - evm/go-x1/utils/uint2hash.go | 27 - evm/go-x1/utils/weighted_shuffle.go | 110 - evm/go-x1/utils/weighted_shuffle_test.go | 99 - evm/go-x1/utils/wgmutex/wg_mutex.go | 25 - evm/go-x1/valkeystore/cache.go | 68 - evm/go-x1/valkeystore/common_test.go | 46 - evm/go-x1/valkeystore/default.go | 20 - .../valkeystore/encryption/encryption.go | 139 - evm/go-x1/valkeystore/encryption/io.go | 29 - evm/go-x1/valkeystore/encryption/migration.go | 45 - evm/go-x1/valkeystore/files.go | 59 - evm/go-x1/valkeystore/files_test.go | 74 - evm/go-x1/valkeystore/keystore.go | 19 - evm/go-x1/valkeystore/mem.go | 61 - evm/go-x1/valkeystore/mem_test.go | 32 - evm/go-x1/valkeystore/signer.go | 43 - evm/go-x1/valkeystore/sync.go | 55 - evm/go-x1/vecmt/index.go | 155 - evm/go-x1/vecmt/index_test.go | 83 - evm/go-x1/vecmt/median_time.go | 84 - evm/go-x1/vecmt/median_time_test.go | 192 - evm/go-x1/vecmt/no_cheaters.go | 34 - evm/go-x1/vecmt/store_vectors.go | 58 - evm/go-x1/vecmt/vector.go | 60 - evm/go-x1/vecmt/vector_ops.go | 93 - evm/go-x1/version/version.go | 46 - evm/go-x1/version/version_test.go | 41 - go-x1 | 1 - 446 files changed, 71396 deletions(-) delete mode 100644 evm/go-x1/.codacy.yml delete mode 100644 evm/go-x1/.dockerignore delete mode 100644 evm/go-x1/.editorconfig delete mode 100644 evm/go-x1/.github/CODEOWNERS delete mode 100644 evm/go-x1/.github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 evm/go-x1/.github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 evm/go-x1/.github/workflows/release_build.yml delete mode 100644 evm/go-x1/.github/workflows/test_build.yml delete mode 100644 evm/go-x1/.goreleaser.yml delete mode 100644 evm/go-x1/.run/testnet.run.xml delete mode 100644 evm/go-x1/.travis.yml delete mode 100644 evm/go-x1/CODE_OF_CONDUCT.md delete mode 100644 evm/go-x1/CONTRIBUTING.md delete mode 100644 evm/go-x1/COPYING.LESSER delete mode 100644 evm/go-x1/FUZZING.md delete mode 100644 evm/go-x1/Makefile delete mode 100644 evm/go-x1/PULL_REQUEST_TEMPLATE.md delete mode 100644 evm/go-x1/README.md delete mode 100644 evm/go-x1/_config.yml delete mode 100644 evm/go-x1/appveyor.yml delete mode 100644 evm/go-x1/cmd/cmdtest/test_cmd.go delete mode 100644 evm/go-x1/cmd/opera/launcher/accountcmd.go delete mode 100644 evm/go-x1/cmd/opera/launcher/accountcmd_test.go delete mode 100644 evm/go-x1/cmd/opera/launcher/chaincmd.go delete mode 100644 evm/go-x1/cmd/opera/launcher/check.go delete mode 100644 evm/go-x1/cmd/opera/launcher/config.go delete mode 100644 evm/go-x1/cmd/opera/launcher/config_custom.go delete mode 100644 evm/go-x1/cmd/opera/launcher/config_custom_test.go delete mode 100644 evm/go-x1/cmd/opera/launcher/consolecmd.go delete mode 100644 evm/go-x1/cmd/opera/launcher/consolecmd_test.go delete mode 100644 evm/go-x1/cmd/opera/launcher/db-transform.go delete mode 100644 evm/go-x1/cmd/opera/launcher/dbcmd.go delete mode 100644 evm/go-x1/cmd/opera/launcher/defaults.go delete mode 100644 evm/go-x1/cmd/opera/launcher/export.go delete mode 100644 evm/go-x1/cmd/opera/launcher/fake.go delete mode 100644 evm/go-x1/cmd/opera/launcher/fake_test.go delete mode 100644 evm/go-x1/cmd/opera/launcher/fixdirty.go delete mode 100644 evm/go-x1/cmd/opera/launcher/genesiscmd.go delete mode 100644 evm/go-x1/cmd/opera/launcher/import.go delete mode 100644 evm/go-x1/cmd/opera/launcher/launcher.go delete mode 100644 evm/go-x1/cmd/opera/launcher/metrics/metrics.go delete mode 100644 evm/go-x1/cmd/opera/launcher/misccmd.go delete mode 100644 evm/go-x1/cmd/opera/launcher/params.go delete mode 100644 evm/go-x1/cmd/opera/launcher/run_test.go delete mode 100644 evm/go-x1/cmd/opera/launcher/snapshotcmd.go delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/dupes/1 delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/dupes/2 delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/dupes/foo delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/empty.js delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/guswallet.json delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/.hiddenfile delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/README delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/aaa delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/empty delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/foo/fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/garbage delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/no-address delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/zero delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/keystore/zzz delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/passwords.txt delete mode 100644 evm/go-x1/cmd/opera/launcher/testdata/wrong-passwords.txt delete mode 100644 evm/go-x1/cmd/opera/launcher/testnet.go delete mode 100644 evm/go-x1/cmd/opera/launcher/tracing/tracing.go delete mode 100644 evm/go-x1/cmd/opera/launcher/usage.go delete mode 100644 evm/go-x1/cmd/opera/launcher/validator.go delete mode 100644 evm/go-x1/cmd/opera/launcher/validatorcmd.go delete mode 100644 evm/go-x1/cmd/opera/launcher/valkeystore.go delete mode 100644 evm/go-x1/cmd/opera/launcher/x1testnet.go delete mode 100644 evm/go-x1/cmd/opera/main.go delete mode 100644 evm/go-x1/debug/api.go delete mode 100644 evm/go-x1/debug/flags.go delete mode 100644 evm/go-x1/debug/loudpanic.go delete mode 100644 evm/go-x1/debug/loudpanic_fallback.go delete mode 100644 evm/go-x1/debug/trace.go delete mode 100644 evm/go-x1/debug/trace_fallback.go delete mode 100644 evm/go-x1/demo/.gitignore delete mode 100755 evm/go-x1/demo/README.md delete mode 100755 evm/go-x1/demo/_params.sh delete mode 100755 evm/go-x1/demo/clean.sh delete mode 100755 evm/go-x1/demo/start.sh delete mode 100755 evm/go-x1/demo/stop.sh delete mode 100644 evm/go-x1/docker/Dockerfile.opera delete mode 100644 evm/go-x1/ethapi/README.md delete mode 100644 evm/go-x1/ethapi/abft_api.go delete mode 100644 evm/go-x1/ethapi/addrlock.go delete mode 100644 evm/go-x1/ethapi/api.go delete mode 100644 evm/go-x1/ethapi/backend.go delete mode 100644 evm/go-x1/ethapi/dag_api.go delete mode 100644 evm/go-x1/ethapi/transaction_args.go delete mode 100644 evm/go-x1/eventcheck/all.go delete mode 100644 evm/go-x1/eventcheck/ban.go delete mode 100644 evm/go-x1/eventcheck/basiccheck/basic_check.go delete mode 100644 evm/go-x1/eventcheck/bvallcheck/all_check.go delete mode 100644 evm/go-x1/eventcheck/epochcheck/epoch_check.go delete mode 100644 evm/go-x1/eventcheck/evallcheck/evallcheck.go delete mode 100644 evm/go-x1/eventcheck/gaspowercheck/gas_power_check.go delete mode 100644 evm/go-x1/eventcheck/heavycheck/adapters.go delete mode 100644 evm/go-x1/eventcheck/heavycheck/config.go delete mode 100644 evm/go-x1/eventcheck/heavycheck/heavy_check.go delete mode 100644 evm/go-x1/eventcheck/parentlesscheck/parentless_check.go delete mode 100644 evm/go-x1/eventcheck/parentscheck/parents_check.go delete mode 100644 evm/go-x1/evmcore/.gitignore delete mode 100644 evm/go-x1/evmcore/apply_fake_genesis.go delete mode 100644 evm/go-x1/evmcore/bench_test.go delete mode 100644 evm/go-x1/evmcore/blocks.go delete mode 100644 evm/go-x1/evmcore/chain_makers.go delete mode 100644 evm/go-x1/evmcore/dummy_block.go delete mode 100644 evm/go-x1/evmcore/error.go delete mode 100644 evm/go-x1/evmcore/evm.go delete mode 100644 evm/go-x1/evmcore/gaspool.go delete mode 100644 evm/go-x1/evmcore/helper_test.go delete mode 100644 evm/go-x1/evmcore/notify.go delete mode 100644 evm/go-x1/evmcore/state_prefetcher.go delete mode 100644 evm/go-x1/evmcore/state_processor.go delete mode 100644 evm/go-x1/evmcore/state_transition.go delete mode 100644 evm/go-x1/evmcore/tx_cacher.go delete mode 100644 evm/go-x1/evmcore/tx_journal.go delete mode 100644 evm/go-x1/evmcore/tx_list.go delete mode 100644 evm/go-x1/evmcore/tx_list_test.go delete mode 100644 evm/go-x1/evmcore/tx_noncer.go delete mode 100644 evm/go-x1/evmcore/tx_pool.go delete mode 100644 evm/go-x1/evmcore/tx_pool_test.go delete mode 100644 evm/go-x1/evmcore/types.go delete mode 100644 evm/go-x1/flags/helpers.go delete mode 100644 evm/go-x1/ftmclient/dag_api.go delete mode 100644 evm/go-x1/ftmclient/ethclient.go delete mode 100644 evm/go-x1/go.mod delete mode 100644 evm/go-x1/go.sum delete mode 100644 evm/go-x1/gossip/api.go delete mode 100644 evm/go-x1/gossip/apply_genesis.go delete mode 100644 evm/go-x1/gossip/basiccheck_test.go delete mode 100644 evm/go-x1/gossip/blockproc/drivermodule/driver_txs.go delete mode 100644 evm/go-x1/gossip/blockproc/eventmodule/confirmed_events_processor.go delete mode 100644 evm/go-x1/gossip/blockproc/evmmodule/evm.go delete mode 100644 evm/go-x1/gossip/blockproc/interface.go delete mode 100644 evm/go-x1/gossip/blockproc/sealmodule/sealer.go delete mode 100644 evm/go-x1/gossip/blockproc/verwatcher/store.go delete mode 100644 evm/go-x1/gossip/blockproc/verwatcher/store_network_version.go delete mode 100644 evm/go-x1/gossip/blockproc/verwatcher/version_watcher.go delete mode 100644 evm/go-x1/gossip/c_block_callbacks.go delete mode 100644 evm/go-x1/gossip/c_block_callbacks_test.go delete mode 100644 evm/go-x1/gossip/c_event_callbacks.go delete mode 100644 evm/go-x1/gossip/c_llr_callbacks.go delete mode 100644 evm/go-x1/gossip/c_llr_callbacks_test.go delete mode 100644 evm/go-x1/gossip/checker_helpers.go delete mode 100644 evm/go-x1/gossip/common_test.go delete mode 100644 evm/go-x1/gossip/config.go delete mode 100644 evm/go-x1/gossip/contract/ballot/Ballot.go delete mode 100644 evm/go-x1/gossip/contract/ballot/Ballot.sol delete mode 100644 evm/go-x1/gossip/contract/ballot/ballot.abi delete mode 100644 evm/go-x1/gossip/contract/ballot/ballot.bin delete mode 100644 evm/go-x1/gossip/contract/contract.go delete mode 100644 evm/go-x1/gossip/contract/driver100/contract.go delete mode 100644 evm/go-x1/gossip/contract/driverauth100/contract.go delete mode 100644 evm/go-x1/gossip/contract/netinit100/contract.go delete mode 100644 evm/go-x1/gossip/contract/sfc100/contract.go delete mode 100644 evm/go-x1/gossip/contract/sfclib100/contract.go delete mode 100644 evm/go-x1/gossip/contract/solc/.gitignore delete mode 100644 evm/go-x1/gossip/discover.go delete mode 100644 evm/go-x1/gossip/dummy_tx_pool.go delete mode 100644 evm/go-x1/gossip/emitter/config.go delete mode 100644 evm/go-x1/gossip/emitter/control.go delete mode 100644 evm/go-x1/gossip/emitter/emitter.go delete mode 100644 evm/go-x1/gossip/emitter/emitter_llr.go delete mode 100644 evm/go-x1/gossip/emitter/emitter_test.go delete mode 100644 evm/go-x1/gossip/emitter/hooks.go delete mode 100644 evm/go-x1/gossip/emitter/mock/world.go delete mode 100644 evm/go-x1/gossip/emitter/originatedtxs/txs_ring_buffer.go delete mode 100644 evm/go-x1/gossip/emitter/parents.go delete mode 100644 evm/go-x1/gossip/emitter/piecefuncs.go delete mode 100644 evm/go-x1/gossip/emitter/prev_action_files.go delete mode 100644 evm/go-x1/gossip/emitter/sync.go delete mode 100644 evm/go-x1/gossip/emitter/txs.go delete mode 100644 evm/go-x1/gossip/emitter/validators.go delete mode 100644 evm/go-x1/gossip/emitter/world.go delete mode 100644 evm/go-x1/gossip/emitter_world.go delete mode 100644 evm/go-x1/gossip/enr_entry.go delete mode 100644 evm/go-x1/gossip/eth_state_adapter.go delete mode 100644 evm/go-x1/gossip/ethapi_backend.go delete mode 100644 evm/go-x1/gossip/evm_state_reader.go delete mode 100644 evm/go-x1/gossip/evm_test.go delete mode 100644 evm/go-x1/gossip/evmstore/apply_genesis.go delete mode 100644 evm/go-x1/gossip/evmstore/config.go delete mode 100644 evm/go-x1/gossip/evmstore/evmpruner/bloom.go delete mode 100644 evm/go-x1/gossip/evmstore/evmpruner/exact.go delete mode 100644 evm/go-x1/gossip/evmstore/evmpruner/pruner.go delete mode 100644 evm/go-x1/gossip/evmstore/store.go delete mode 100644 evm/go-x1/gossip/evmstore/store_block_cache.go delete mode 100644 evm/go-x1/gossip/evmstore/store_receipts.go delete mode 100644 evm/go-x1/gossip/evmstore/store_receipts_test.go delete mode 100644 evm/go-x1/gossip/evmstore/store_test.go delete mode 100644 evm/go-x1/gossip/evmstore/store_tx.go delete mode 100644 evm/go-x1/gossip/evmstore/store_tx_position.go delete mode 100644 evm/go-x1/gossip/evmstore/utils.go delete mode 100644 evm/go-x1/gossip/execqueue.go delete mode 100644 evm/go-x1/gossip/filters/api.go delete mode 100644 evm/go-x1/gossip/filters/api_test.go delete mode 100644 evm/go-x1/gossip/filters/filter.go delete mode 100644 evm/go-x1/gossip/filters/filter_system.go delete mode 100644 evm/go-x1/gossip/filters/filter_system_test.go delete mode 100644 evm/go-x1/gossip/filters/filter_test.go delete mode 100644 evm/go-x1/gossip/gasprice/constructive.go delete mode 100644 evm/go-x1/gossip/gasprice/gasprice.go delete mode 100644 evm/go-x1/gossip/gasprice/gasprice_test.go delete mode 100644 evm/go-x1/gossip/gasprice/reactive.go delete mode 100644 evm/go-x1/gossip/gpo_backend.go delete mode 100644 evm/go-x1/gossip/handler.go delete mode 100644 evm/go-x1/gossip/handler_fuzz.go delete mode 100644 evm/go-x1/gossip/handler_snap.go delete mode 100644 evm/go-x1/gossip/heavycheck_test.go delete mode 100644 evm/go-x1/gossip/mps_test.go delete mode 100644 evm/go-x1/gossip/peer.go delete mode 100644 evm/go-x1/gossip/peerset.go delete mode 100644 evm/go-x1/gossip/proclogger/dag_logger.go delete mode 100644 evm/go-x1/gossip/proclogger/llr_logger.go delete mode 100644 evm/go-x1/gossip/protocol.go delete mode 100644 evm/go-x1/gossip/protocols/blockrecords/brprocessor/config.go delete mode 100644 evm/go-x1/gossip/protocols/blockrecords/brprocessor/processor.go delete mode 100644 evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamleecher/config.go delete mode 100644 evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamleecher/leecher.go delete mode 100644 evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamseeder/config.go delete mode 100644 evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamseeder/seeder.go delete mode 100644 evm/go-x1/gossip/protocols/blockrecords/brstream/types.go delete mode 100644 evm/go-x1/gossip/protocols/blockvotes/bvprocessor/config.go delete mode 100644 evm/go-x1/gossip/protocols/blockvotes/bvprocessor/processor.go delete mode 100644 evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamleecher/config.go delete mode 100644 evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamleecher/leecher.go delete mode 100644 evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamseeder/config.go delete mode 100644 evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamseeder/seeder.go delete mode 100644 evm/go-x1/gossip/protocols/blockvotes/bvstream/types.go delete mode 100644 evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/config.go delete mode 100644 evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/leecher.go delete mode 100644 evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/leecher_test.go delete mode 100644 evm/go-x1/gossip/protocols/dag/dagstream/dagstreamseeder/config.go delete mode 100644 evm/go-x1/gossip/protocols/dag/dagstream/dagstreamseeder/seeder.go delete mode 100644 evm/go-x1/gossip/protocols/dag/dagstream/types.go delete mode 100644 evm/go-x1/gossip/protocols/epochpacks/epprocessor/config.go delete mode 100644 evm/go-x1/gossip/protocols/epochpacks/epprocessor/processor.go delete mode 100644 evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamleecher/config.go delete mode 100644 evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamleecher/leecher.go delete mode 100644 evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamseeder/config.go delete mode 100644 evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamseeder/seeder.go delete mode 100644 evm/go-x1/gossip/protocols/epochpacks/epstream/types.go delete mode 100644 evm/go-x1/gossip/protocols/snap/api.go delete mode 100644 evm/go-x1/gossip/protocols/snap/events.go delete mode 100644 evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/leecher.go delete mode 100644 evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/peer.go delete mode 100644 evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/statesync.go delete mode 100644 evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/types.go delete mode 100644 evm/go-x1/gossip/randselect.go delete mode 100644 evm/go-x1/gossip/service.go delete mode 100644 evm/go-x1/gossip/sfc_test.go delete mode 100644 evm/go-x1/gossip/store.go delete mode 100644 evm/go-x1/gossip/store_activation_heights.go delete mode 100644 evm/go-x1/gossip/store_block.go delete mode 100644 evm/go-x1/gossip/store_decided_state.go delete mode 100644 evm/go-x1/gossip/store_epoch.go delete mode 100644 evm/go-x1/gossip/store_event.go delete mode 100644 evm/go-x1/gossip/store_heads.go delete mode 100644 evm/go-x1/gossip/store_last_bv.go delete mode 100644 evm/go-x1/gossip/store_last_ev.go delete mode 100644 evm/go-x1/gossip/store_last_events.go delete mode 100644 evm/go-x1/gossip/store_llr_block.go delete mode 100644 evm/go-x1/gossip/store_llr_epoch.go delete mode 100644 evm/go-x1/gossip/store_llr_state.go delete mode 100644 evm/go-x1/gossip/store_migration.go delete mode 100644 evm/go-x1/gossip/sync.go delete mode 100644 evm/go-x1/gossip/tflusher.go delete mode 100644 evm/go-x1/integration/assembly.go delete mode 100644 evm/go-x1/integration/bench_db_flush_test.go delete mode 100644 evm/go-x1/integration/db.go delete mode 100644 evm/go-x1/integration/diskusage.go delete mode 100644 evm/go-x1/integration/diskusage_openbsd.go delete mode 100644 evm/go-x1/integration/diskusage_windows.go delete mode 100644 evm/go-x1/integration/legacy_migrate.go delete mode 100644 evm/go-x1/integration/makefakegenesis/genesis.go delete mode 100644 evm/go-x1/integration/makegenesis/genesis.go delete mode 100644 evm/go-x1/integration/maketestnetgenesis/genesis.go delete mode 100644 evm/go-x1/integration/metric.go delete mode 100644 evm/go-x1/integration/metric_test.go delete mode 100644 evm/go-x1/integration/presets.go delete mode 100644 evm/go-x1/integration/routing.go delete mode 100644 evm/go-x1/integration/status.go delete mode 100644 evm/go-x1/inter/block.go delete mode 100644 evm/go-x1/inter/drivertype/driver_type.go delete mode 100644 evm/go-x1/inter/event.go delete mode 100644 evm/go-x1/inter/event_serializer.go delete mode 100644 evm/go-x1/inter/event_serializer_test.go delete mode 100644 evm/go-x1/inter/event_test.go delete mode 100644 evm/go-x1/inter/events.go delete mode 100644 evm/go-x1/inter/gas_power_left.go delete mode 100644 evm/go-x1/inter/gas_power_left_test.go delete mode 100644 evm/go-x1/inter/iblockproc/decided_state.go delete mode 100644 evm/go-x1/inter/iblockproc/legacy.go delete mode 100644 evm/go-x1/inter/iblockproc/profiles.go delete mode 100644 evm/go-x1/inter/ibr/inter_block_records.go delete mode 100644 evm/go-x1/inter/iep/inter_epoch_packs.go delete mode 100644 evm/go-x1/inter/ier/inter_epoch_records.go delete mode 100644 evm/go-x1/inter/inter_llr.go delete mode 100644 evm/go-x1/inter/inter_llr_test.go delete mode 100644 evm/go-x1/inter/inter_mps.go delete mode 100644 evm/go-x1/inter/signature.go delete mode 100644 evm/go-x1/inter/time.go delete mode 100644 evm/go-x1/inter/transaction_serializer.go delete mode 100644 evm/go-x1/inter/transaction_serializer_test.go delete mode 100644 evm/go-x1/inter/validatorpk/pubkey.go delete mode 100644 evm/go-x1/inter/validatorpk/pubkey_test.go delete mode 100644 evm/go-x1/logger/instance.go delete mode 100644 evm/go-x1/logger/logger.go delete mode 100644 evm/go-x1/logger/logrus.go delete mode 100644 evm/go-x1/logger/periodic_log.go delete mode 100644 evm/go-x1/logger/test_output.go delete mode 100644 evm/go-x1/opera/contracts/driver/driver_predeploy.go delete mode 100644 evm/go-x1/opera/contracts/driver/drivercall/driver_calls.go delete mode 100644 evm/go-x1/opera/contracts/driver/driverpos/positions.go delete mode 100644 evm/go-x1/opera/contracts/driverauth/driverauth.go delete mode 100644 evm/go-x1/opera/contracts/emitterdriver/emitterdriver.go delete mode 100644 evm/go-x1/opera/contracts/evmwriter/evm_writer.go delete mode 100644 evm/go-x1/opera/contracts/evmwriter/evm_writer_test.go delete mode 100644 evm/go-x1/opera/contracts/netinit/netinitcalls/network_initializer_calls.go delete mode 100644 evm/go-x1/opera/contracts/netinit/network_initializer.go delete mode 100644 evm/go-x1/opera/contracts/sfc/sfc_predeploy.go delete mode 100644 evm/go-x1/opera/contracts/sfclib/sfclib_predeploy.go delete mode 100644 evm/go-x1/opera/genesis/gpos/validators.go delete mode 100644 evm/go-x1/opera/genesis/types.go delete mode 100644 evm/go-x1/opera/genesisstore/disk.go delete mode 100644 evm/go-x1/opera/genesisstore/filelog/filelog.go delete mode 100644 evm/go-x1/opera/genesisstore/fileshash/filehash_test.go delete mode 100644 evm/go-x1/opera/genesisstore/fileshash/reader_file.go delete mode 100644 evm/go-x1/opera/genesisstore/fileshash/reader_map.go delete mode 100644 evm/go-x1/opera/genesisstore/fileshash/write_file.go delete mode 100644 evm/go-x1/opera/genesisstore/readersmap/reader_map.go delete mode 100644 evm/go-x1/opera/genesisstore/store.go delete mode 100644 evm/go-x1/opera/genesisstore/store_genesis.go delete mode 100644 evm/go-x1/opera/legacy_serialization.go delete mode 100644 evm/go-x1/opera/marshal.go delete mode 100644 evm/go-x1/opera/marshal_test.go delete mode 100644 evm/go-x1/opera/rules.go delete mode 100644 evm/go-x1/sonar-project.properties delete mode 100644 evm/go-x1/topicsdb/index.go delete mode 100644 evm/go-x1/topicsdb/key.go delete mode 100644 evm/go-x1/topicsdb/key_test.go delete mode 100644 evm/go-x1/topicsdb/record.go delete mode 100644 evm/go-x1/topicsdb/search_parallel.go delete mode 100644 evm/go-x1/topicsdb/search_test.go delete mode 100644 evm/go-x1/topicsdb/sync.go delete mode 100644 evm/go-x1/topicsdb/thread_pool.go delete mode 100644 evm/go-x1/topicsdb/topicsdb.go delete mode 100644 evm/go-x1/topicsdb/topicsdb_test.go delete mode 100644 evm/go-x1/tracing/tx-tracing.go delete mode 100644 evm/go-x1/utils/adapters/ethdb2kvdb/adapter.go delete mode 100644 evm/go-x1/utils/adapters/kvdb2ethdb/adapter.go delete mode 100644 evm/go-x1/utils/adapters/snap2kvdb/adapter.go delete mode 100644 evm/go-x1/utils/adapters/vecmt2dagidx/vecmt2lachesis.go delete mode 100644 evm/go-x1/utils/bitmap/bitset.go delete mode 100644 evm/go-x1/utils/bits/bits.go delete mode 100644 evm/go-x1/utils/bits/bits_test.go delete mode 100644 evm/go-x1/utils/concurrent/ValidatorBlocksSet.go delete mode 100644 evm/go-x1/utils/concurrent/ValidatorEpochsSet.go delete mode 100644 evm/go-x1/utils/concurrent/ValidatorEventsSet.go delete mode 100644 evm/go-x1/utils/concurrent/events.go delete mode 100644 evm/go-x1/utils/cser/binary.go delete mode 100644 evm/go-x1/utils/cser/binary_test.go delete mode 100644 evm/go-x1/utils/cser/read_writer.go delete mode 100644 evm/go-x1/utils/cser/read_writer_test.go delete mode 100644 evm/go-x1/utils/dbutil/asyncflushproducer/producer.go delete mode 100644 evm/go-x1/utils/dbutil/asyncflushproducer/store.go delete mode 100644 evm/go-x1/utils/dbutil/autocompact/store.go delete mode 100644 evm/go-x1/utils/dbutil/autocompact/strategy.go delete mode 100644 evm/go-x1/utils/dbutil/compactdb/compactdb.go delete mode 100644 evm/go-x1/utils/dbutil/compactdb/keys.go delete mode 100644 evm/go-x1/utils/dbutil/compactdb/keys_test.go delete mode 100644 evm/go-x1/utils/dbutil/compactdb/log.go delete mode 100644 evm/go-x1/utils/dbutil/dbcounter/dbcounter.go delete mode 100644 evm/go-x1/utils/dbutil/itergc/iterator_gc.go delete mode 100644 evm/go-x1/utils/dbutil/switchable/snapshot.go delete mode 100644 evm/go-x1/utils/dbutil/switchable/snapshot_test.go delete mode 100644 evm/go-x1/utils/dbutil/threads/counted.go delete mode 100644 evm/go-x1/utils/dbutil/threads/pool.go delete mode 100644 evm/go-x1/utils/dbutil/threads/pool_test.go delete mode 100644 evm/go-x1/utils/devnullfile/devnull.go delete mode 100644 evm/go-x1/utils/errlock/errlock.go delete mode 100644 evm/go-x1/utils/eventid/eventid.go delete mode 100644 evm/go-x1/utils/fast/buffer.go delete mode 100644 evm/go-x1/utils/fast/buffer_test.go delete mode 100644 evm/go-x1/utils/file.go delete mode 100644 evm/go-x1/utils/iodb/io_db.go delete mode 100644 evm/go-x1/utils/ioread/ioread.go delete mode 100644 evm/go-x1/utils/memory/LICENSE delete mode 100644 evm/go-x1/utils/memory/doc.go delete mode 100644 evm/go-x1/utils/memory/memory_bsd.go delete mode 100644 evm/go-x1/utils/memory/memory_darwin.go delete mode 100644 evm/go-x1/utils/memory/memory_linux.go delete mode 100644 evm/go-x1/utils/memory/memory_test.go delete mode 100644 evm/go-x1/utils/memory/memory_windows.go delete mode 100644 evm/go-x1/utils/memory/memsysctl.go delete mode 100644 evm/go-x1/utils/memory/stub.go delete mode 100644 evm/go-x1/utils/migration/id_store.go delete mode 100644 evm/go-x1/utils/migration/kvdb_id_store.go delete mode 100644 evm/go-x1/utils/migration/migration.go delete mode 100644 evm/go-x1/utils/migration/migration_test.go delete mode 100644 evm/go-x1/utils/nameof.go delete mode 100644 evm/go-x1/utils/num_queue.go delete mode 100644 evm/go-x1/utils/num_queue_test.go delete mode 100644 evm/go-x1/utils/pretty_duration.go delete mode 100644 evm/go-x1/utils/pretty_duration_test.go delete mode 100644 evm/go-x1/utils/randat/rand_at.go delete mode 100644 evm/go-x1/utils/rate/gauge.go delete mode 100644 evm/go-x1/utils/rate/gauge_test.go delete mode 100644 evm/go-x1/utils/rlpstore/rlpstore.go delete mode 100644 evm/go-x1/utils/self-table.go delete mode 100644 evm/go-x1/utils/signers/gsignercache/global_cache.go delete mode 100644 evm/go-x1/utils/signers/internaltx/internaltx.go delete mode 100644 evm/go-x1/utils/signers/internaltx/internaltx_test.go delete mode 100644 evm/go-x1/utils/spin_lock.go delete mode 100644 evm/go-x1/utils/to_ftm.go delete mode 100644 evm/go-x1/utils/txtime/txtime.go delete mode 100644 evm/go-x1/utils/uint2hash.go delete mode 100644 evm/go-x1/utils/weighted_shuffle.go delete mode 100644 evm/go-x1/utils/weighted_shuffle_test.go delete mode 100644 evm/go-x1/utils/wgmutex/wg_mutex.go delete mode 100644 evm/go-x1/valkeystore/cache.go delete mode 100644 evm/go-x1/valkeystore/common_test.go delete mode 100644 evm/go-x1/valkeystore/default.go delete mode 100644 evm/go-x1/valkeystore/encryption/encryption.go delete mode 100644 evm/go-x1/valkeystore/encryption/io.go delete mode 100644 evm/go-x1/valkeystore/encryption/migration.go delete mode 100644 evm/go-x1/valkeystore/files.go delete mode 100644 evm/go-x1/valkeystore/files_test.go delete mode 100644 evm/go-x1/valkeystore/keystore.go delete mode 100644 evm/go-x1/valkeystore/mem.go delete mode 100644 evm/go-x1/valkeystore/mem_test.go delete mode 100644 evm/go-x1/valkeystore/signer.go delete mode 100644 evm/go-x1/valkeystore/sync.go delete mode 100644 evm/go-x1/vecmt/index.go delete mode 100644 evm/go-x1/vecmt/index_test.go delete mode 100644 evm/go-x1/vecmt/median_time.go delete mode 100644 evm/go-x1/vecmt/median_time_test.go delete mode 100644 evm/go-x1/vecmt/no_cheaters.go delete mode 100644 evm/go-x1/vecmt/store_vectors.go delete mode 100644 evm/go-x1/vecmt/vector.go delete mode 100644 evm/go-x1/vecmt/vector_ops.go delete mode 100644 evm/go-x1/version/version.go delete mode 100644 evm/go-x1/version/version_test.go delete mode 160000 go-x1 diff --git a/evm/go-x1/.codacy.yml b/evm/go-x1/.codacy.yml deleted file mode 100644 index 4391669..0000000 --- a/evm/go-x1/.codacy.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -engines: - rubocop: - enabled: true - exclude_paths: - - config/engines.yml - duplication: - enabled: true - exclude_paths: - - config/engines.yml - metrics: - enabled: true - exclude_paths: - - config/engines.yml - coverage: - enabled: true - exclude_paths: - - config/engines.yml -languages: - css: - extensions: - - '-css.resource' -exclude_paths: -- '.bundle/**' -- 'spec/**/*' -- 'benchmarks/**/*' -- '*.min.js' -- '**/*.pb.go' -- '**/tests/**' diff --git a/evm/go-x1/.dockerignore b/evm/go-x1/.dockerignore deleted file mode 100644 index 5657f6e..0000000 --- a/evm/go-x1/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -vendor \ No newline at end of file diff --git a/evm/go-x1/.editorconfig b/evm/go-x1/.editorconfig deleted file mode 100644 index 2f18c02..0000000 --- a/evm/go-x1/.editorconfig +++ /dev/null @@ -1,21 +0,0 @@ -root = true - -[*] -end_of_line = lf -insert_final_newline = true -charset = utf-8 - -[*.go] -indent_style = tab -tab_width = 4 - -[Makefile] -indent_style = tab - -[*.yml] -indent_style = space -indent_size = 2 - -[*.proto] -indent_style = space -indent_size = 2 diff --git a/evm/go-x1/.github/CODEOWNERS b/evm/go-x1/.github/CODEOWNERS deleted file mode 100644 index 0f12394..0000000 --- a/evm/go-x1/.github/CODEOWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# Golang files: -*.go @andrecronje diff --git a/evm/go-x1/.github/ISSUE_TEMPLATE/bug_report.md b/evm/go-x1/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index b735373..0000000 --- a/evm/go-x1/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] - -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] - -**Additional context** -Add any other context about the problem here. diff --git a/evm/go-x1/.github/ISSUE_TEMPLATE/feature_request.md b/evm/go-x1/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 066b2d9..0000000 --- a/evm/go-x1/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/evm/go-x1/.github/workflows/release_build.yml b/evm/go-x1/.github/workflows/release_build.yml deleted file mode 100644 index d3b97e1..0000000 --- a/evm/go-x1/.github/workflows/release_build.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Release - -on: - push: - tags: - - '*' - -jobs: - release: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Golang dependency - uses: actions/setup-go@v3 - with: - go-version: '^1.18' - - - name: Run unit tests - run: go test -v ./... - - - name: Build - run: make opera - - - name: Release - uses: ncipollo/release-action@v1 - with: - artifacts: "./build/opera" - token: ${{ secrets.GITHUB_TOKEN }} diff --git a/evm/go-x1/.github/workflows/test_build.yml b/evm/go-x1/.github/workflows/test_build.yml deleted file mode 100644 index 56e9204..0000000 --- a/evm/go-x1/.github/workflows/test_build.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Check build - -on: - push: - pull_request: - branches: - - develop - - master - -jobs: - check-build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Golang dependency - uses: actions/setup-go@v3 - with: - go-version: '^1.18' - - - name: Run unit tests - run: go test -v ./... - - - name: Build - run: make opera - - - name: Publish - uses: actions/upload-artifact@v2 - with: - name: opera - path: ./build/opera diff --git a/evm/go-x1/.goreleaser.yml b/evm/go-x1/.goreleaser.yml deleted file mode 100644 index 7dabbc8..0000000 --- a/evm/go-x1/.goreleaser.yml +++ /dev/null @@ -1,58 +0,0 @@ -before: - hooks: - - make clean proto vendor -builds: - - main: ./cmd/opera/main.go - binary: go-opera - ldflags: - - -linkmode external -extldflags -static -s -w - - -X main.gitCommit={{ .ShortCommit }} - env: - - CGO_ENABLED=0 - goos: - - linux - goarch: - - amd64 -archive: - replacements: - darwin: Darwin - linux: Linux - windows: Windows - 386: i386 - amd64: x86_64 -checksum: - name_template: 'checksums.txt' -snapshot: - name_template: "{{ .Tag }}-next" -changelog: - sort: asc - filters: - exclude: - - '^docs:' - - '^test:' -nfpm: - name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" - replacements: - amd64: 64-bit - 386: 32-bit - darwin: macOS - linux: Tux - - vendor: Fanton Foundation - homepage: https://fantom.foundation - maintainer: Samuel Marks - description: BFT Consensus platform for distributed applications. - license: MIT - - formats: - - deb - - rpm - - empty_folders: - - /var/log/go-opera - - files: - "scripts/daemon/go-opera.service": "/lib/systemd/system/go-opera.service" - - # scripts: - # preinstall: "scripts/preinstall.bash" diff --git a/evm/go-x1/.run/testnet.run.xml b/evm/go-x1/.run/testnet.run.xml deleted file mode 100644 index b41aa3c..0000000 --- a/evm/go-x1/.run/testnet.run.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/evm/go-x1/.travis.yml b/evm/go-x1/.travis.yml deleted file mode 100644 index 78442ed..0000000 --- a/evm/go-x1/.travis.yml +++ /dev/null @@ -1,43 +0,0 @@ -language: go - -go: - - 1.14.x - -go_import_path: github.com/Fantom-foundation/go-opera - -cache: - directories: - - $GOPATH/pkg - -env: - global: - - GO111MODULE=on - -# install: skip - -script: - - go build -v ./... - -after_success: - - | - if [ -n "$GO_TEST" ]; then - go test -coverprofile=coverage.txt -covermode=atomic ./... - elif [ -n "$GO_INTEGRATION_TEST" ]; then - go test ./integration/ - fi - -after_script: - - | - if [ -n "$GO_TEST" ]; then - bash <(curl -s https://codecov.io/bash) - fi - -matrix: - include: - - name: go test - env: - - GO_TEST=1 - - - name: testnet - env: - - GO_INTEGRATION_TEST=1 diff --git a/evm/go-x1/CODE_OF_CONDUCT.md b/evm/go-x1/CODE_OF_CONDUCT.md deleted file mode 100644 index ea8d287..0000000 --- a/evm/go-x1/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,46 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at https://t.me/XENCryptoTalk. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/evm/go-x1/CONTRIBUTING.md b/evm/go-x1/CONTRIBUTING.md deleted file mode 100644 index 6be70fa..0000000 --- a/evm/go-x1/CONTRIBUTING.md +++ /dev/null @@ -1,112 +0,0 @@ -# Contributing - -When contributing to this repository, please first discuss the change you wish to make via issue, -email, or any other method with the owners of this repository before making a change. - -Please note we have a code of conduct, please follow it in all your interactions with the project. - -## Contribution Guidelines - -1. Ensure any install or build dependencies are removed before the end of the layer when doing a - build. -2. Update the README.md with details of changes to the interface, this includes new environment - variables, exposed ports, useful file locations and container parameters. -3. Increase the version numbers in any examples files and the README.md to the new version that this - Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). -4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you - do not have permission to do that, you may request the second reviewer to merge it for you. - -## Code of Conduct - -### Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. - -### Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -### Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -### Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -### Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at [INSERT EMAIL ADDRESS]. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -### Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ - -## Quality standards - -To be accepted, the PR should adhere to these quality standards (https://goreportcard.com/report/github.com/ **github_user** / **github_repo**): - -- Code functions as documented and expected -- Generally useful to the wider community of Go programmers -- Thoroughly documented (README, godoc comments, etc.) in english language, so everyone is able to understand the project's intention and how it works -- Tests, where practical. If the library/program is testable, then coverage should be >= 80% for non-data-related packages and >=90% for data related packages. **Notice**: the tests will be reviewed too. - -## Maintainers - -The maintainers will review your PR and notify you and tag it in case any -information is still missing. They will wait 8 days for your interaction, after -that the PR will be closed. - - -## Reporting issues - -Please open an issue if you would like to discuss anything that could be improved or have suggestions. diff --git a/evm/go-x1/COPYING.LESSER b/evm/go-x1/COPYING.LESSER deleted file mode 100644 index 5357f69..0000000 --- a/evm/go-x1/COPYING.LESSER +++ /dev/null @@ -1,166 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. - diff --git a/evm/go-x1/FUZZING.md b/evm/go-x1/FUZZING.md deleted file mode 100644 index d8bf3ba..0000000 --- a/evm/go-x1/FUZZING.md +++ /dev/null @@ -1,34 +0,0 @@ -## Fuzzing - -Fuzzing is mainly applicable to packages that parse complex inputs (both text and binary), and is especially useful for hardening of systems that parse inputs from potentially malicious users (e.g. anything accepted over a network). -To run a p2p protocol fuzzer locally, use the command: - -``` -make fuzz -``` -That command should generate a `gossip-fuzz.zip` in the `fuzzing/` directory and runs fuzzer: - -``` -2020/12/30 22:50:51 workers: 0, corpus: 1 (3s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 3s -2020/12/30 22:50:54 workers: 0, corpus: 1 (6s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 6s -2020/12/30 22:50:57 workers: 3, corpus: 1 (9s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 9s -2020/12/30 22:51:00 workers: 3, corpus: 1 (12s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 12s -2020/12/30 22:51:03 workers: 3, corpus: 1 (15s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 15s -2020/12/30 22:51:06 workers: 3, corpus: 1 (18s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 18s -2020/12/30 22:51:09 workers: 3, corpus: 1 (21s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 21s -2020/12/30 22:51:12 workers: 3, corpus: 1 (24s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 24s -2020/12/30 22:51:15 workers: 3, corpus: 1 (27s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 27s -2020/12/30 22:51:18 workers: 3, corpus: 1 (30s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 30s -2020/12/30 22:51:21 workers: 3, corpus: 1 (33s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 33s -2020/12/30 22:51:24 workers: 3, corpus: 1 (36s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 36s -2020/12/30 22:51:27 workers: 3, corpus: 1 (39s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 39s -2020/12/30 22:51:30 workers: 3, corpus: 1 (42s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 42s -``` - -See [github.com/dvyukov/go-fuzz](https://github.com/dvyukov/go-fuzz) to get more details. - - -### Notes - -Once a 'crasher' is found, the fuzzer tries to avoid reporting the same vector twice, so stores the fault in the `suppressions` folder. Thus, if you -e.g. make changes to fix a bug, you should _remove_ all data from the `suppressions`-folder, to verify that the issue is indeed resolved. diff --git a/evm/go-x1/Makefile b/evm/go-x1/Makefile deleted file mode 100644 index 089a6d5..0000000 --- a/evm/go-x1/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -.PHONY: all -all: x1 - -GOPROXY ?= "https://proxy.golang.org,direct" -.PHONY: x1 -x1: - GIT_COMMIT=`git rev-list -1 HEAD 2>/dev/null || echo ""` && \ - GIT_DATE=`git log -1 --date=short --pretty=format:%ct 2>/dev/null || echo ""` && \ - GOPROXY=$(GOPROXY) \ - go build \ - -ldflags "-s -w -X github.com/Fantom-foundation/go-opera/cmd/opera/launcher.gitCommit=$${GIT_COMMIT} -X github.com/Fantom-foundation/go-opera/cmd/opera/launcher.gitDate=$${GIT_DATE}" \ - -o build/x1 \ - ./cmd/opera - - -TAG ?= "latest" -.PHONY: x1-image -x1-image: - docker build \ - --network=host \ - -f ./docker/Dockerfile.opera -t "x1:$(TAG)" . - -.PHONY: test -test: - go test ./... - -.PHONY: coverage -coverage: - go test -coverprofile=cover.prof $$(go list ./... | grep -v '/gossip/contract/' | grep -v '/gossip/emitter/mock' | xargs) - go tool cover -func cover.prof | grep -e "^total:" - -.PHONY: fuzz -fuzz: - CGO_ENABLED=1 \ - mkdir -p ./fuzzing && \ - go run github.com/dvyukov/go-fuzz/go-fuzz-build -o=./fuzzing/gossip-fuzz.zip ./gossip && \ - go run github.com/dvyukov/go-fuzz/go-fuzz -workdir=./fuzzing -bin=./fuzzing/gossip-fuzz.zip - - -.PHONY: clean -clean: - rm -fr ./build/* diff --git a/evm/go-x1/PULL_REQUEST_TEMPLATE.md b/evm/go-x1/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 8dea5f6..0000000 --- a/evm/go-x1/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,17 +0,0 @@ -Please check if what you want to add to `go-opera` list meets [quality standards](https://github.com/Fantom-foundation/go-opera/blob/master/CONTRIBUTING.md#quality-standard) before sending pull request. - -**Please provide package links to:** - -- github.com repo: -- godoc.org: -- goreportcard.com: -- coverage service link ([cover.run](https://cover.run/), [gocover](http://gocover.io/), [coveralls](https://coveralls.io/) etc.), example: `[![cover.run](https://cover.run/go/github.com/user/repository.svg?style=flat&tag=golang-1.10)](https://cover.run/go?tag=golang-1.10&repo=github.com%2Fuser%2Frepository)` - -**Make sure that you've checked the boxes below before you submit PR:** -- [ ] I have added my package in alphabetical order. -- [ ] I have an appropriate description with correct grammar. -- [ ] I know that this package was not listed before. -- [ ] I have added godoc link to the repo and to my pull request. -- [ ] I have added coverage service link to the repo and to my pull request. -- [ ] I have added goreportcard link to the repo and to my pull request. -- [ ] I have read [Contribution guidelines](https://github.com/Fantom-foundation/go-opera/blob/master/CONTRIBUTING.md#contribution-guidelines), [maintainers note](https://github.com/Fantom-foundation/go-opera/blob/master/CONTRIBUTING.md#maintainers) and [Quality standard](https://github.com/Fantom-foundation/go-opera/blob/master/CONTRIBUTING.md#quality-standard). diff --git a/evm/go-x1/README.md b/evm/go-x1/README.md deleted file mode 100644 index 3712b8b..0000000 --- a/evm/go-x1/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# X1 - -X1 is a simple, fast, and secure EVM-compatible network for the next generation of decentralized applications powered by Lachesis consensus algorithm. - -## Explore the Network (Testnet) - -- [X1 Explorer](https://explorer.x1-testnet.xen.network) - -RPC Endpoints - -- https://x1-testnet.xen.network/ -- wss://x1-testnet.xen.network - -## Run Full Node (Testnet) - -> Quick start a full node and run in the foreground - -```shell -# Install dependencies (ex: ubuntu) -apt update -y -apt install -y golang wget git make - -# Clone and build the X1 binary -git clone --branch x1 https://github.com/FairCrypto/go-x1 -cd go-x1 -make x1 -cp build/x1 /usr/local/bin - -# Run the node -x1 --testnet --syncmode snap -``` diff --git a/evm/go-x1/_config.yml b/evm/go-x1/_config.yml deleted file mode 100644 index 190d79a..0000000 --- a/evm/go-x1/_config.yml +++ /dev/null @@ -1,28 +0,0 @@ -title: Xen Crypto Documentation -description: XEN is a cryptocurrency for the masses. It is designed and built to deliver on the First Principles of Crypto. -url: https://docs.xen.network/ - -author: - name: Fair Crypto Foundation - url: https://faircrypto.org - -plugins: - - jekyll-remote-theme - - jekyll-titles-from-headings -remote_theme: FairCrypto/minima -minima: - skin: auto - social_links: - - { platform: github, user_url: "https://github.com/FairCrypto/go-x1" } - - { platform: twitter, user_url: "https://twitter.com/XEN_Crypto" } - - { platform: telegram, user_url: "https://t.me/XENCryptoTalk" } - - { platform: youtube, user_url: "https://m.youtube.com/channel/UCiw5nyHHt9BPHvoRbcGNehA/playlists" } -show_excerpts: false - -titles_from_headings: - enabled: true - strip_title: true - collections: false - -header_pages: - - index.md diff --git a/evm/go-x1/appveyor.yml b/evm/go-x1/appveyor.yml deleted file mode 100644 index fdab51a..0000000 --- a/evm/go-x1/appveyor.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: 0.4.5-rc1#{build} -image: Visual Studio 2017 - -build: off - -clone_folder: c:\gopath\src\github.com\Fantom-foundation\go-opera - -environment: - PATH: C:\gopath\bin;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin;C:\PROGRA~1\Git\bin;C:\PROGRA~1\Git\usr\bin\;C:\ProgramData\chocolatey\bin;$(PATH) - GOPATH: c:\gopath - GO111MODULE: on - -stack: go 1.14 - -init: - - choco install make mingw - -cache: - - C:\usr - - C:\ProgramData\chocolatey - -before_test: - - ps: Set-NetFirewallProfile -All -Enabled False - - ps: Disable-NetFirewallRule -All - -test_script: - - go test -v ./... diff --git a/evm/go-x1/cmd/cmdtest/test_cmd.go b/evm/go-x1/cmd/cmdtest/test_cmd.go deleted file mode 100644 index 49642a9..0000000 --- a/evm/go-x1/cmd/cmdtest/test_cmd.go +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package cmdtest - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "regexp" - "strings" - "sync" - "syscall" - "testing" - "text/template" - - "github.com/docker/docker/pkg/reexec" -) - -func NewTestCmd(t *testing.T, data interface{}) *TestCmd { - return &TestCmd{T: t, Data: data} -} - -type TestCmd struct { - // For total convenience, all testing methods are available. - *testing.T - - Func template.FuncMap - Data interface{} - Cleanup func() - - cmd *exec.Cmd - stdout *bufio.Reader - stdin io.WriteCloser - stderr *testlogger - // Err will contain the process exit error or interrupt signal error - Err error -} - -// Run exec's the current binary using name as argv[0] which will trigger the -// reexec init function for that name (e.g. "opera-test" in cmd/run_test.go) -func (tt *TestCmd) Run(name string, args ...string) { - tt.stderr = &testlogger{t: tt.T} - tt.cmd = &exec.Cmd{ - Path: reexec.Self(), - Args: append([]string{name}, args...), - Stderr: tt.stderr, - } - stdout, err := tt.cmd.StdoutPipe() - if err != nil { - tt.Fatal(err) - } - tt.stdout = bufio.NewReader(stdout) - if tt.stdin, err = tt.cmd.StdinPipe(); err != nil { - tt.Fatal(err) - } - if err := tt.cmd.Start(); err != nil { - tt.Fatal(err) - } -} - -// InputLine writes the given text to the childs stdin. -// This method can also be called from an expect template, e.g.: -// -// cli.expect(`Passphrase: {{.InputLine "password"}}`) -func (tt *TestCmd) InputLine(s string) string { - io.WriteString(tt.stdin, s+"\n") - return "" -} - -func (tt *TestCmd) SetTemplateFunc(name string, fn interface{}) { - if tt.Func == nil { - tt.Func = make(map[string]interface{}) - } - tt.Func[name] = fn -} - -// Expect runs its argument as a template, then expects the -// child process to output the result of the template within 5s. -// -// If the template starts with a newline, the newline is removed -// before matching. -func (tt *TestCmd) Expect(tplsource string) { - // Generate the expected output by running the template. - tpl := template.Must(template.New("").Funcs(tt.Func).Parse(tplsource)) - wantbuf := new(bytes.Buffer) - if err := tpl.Execute(wantbuf, tt.Data); err != nil { - panic(err) - } - // Trim exactly one newline at the beginning. This makes tests look - // much nicer because all expect strings are at column 0. - want := bytes.TrimPrefix(wantbuf.Bytes(), []byte("\n")) - if err := tt.matchExactOutput(want); err != nil { - tt.Fatal(err) - } - tt.Logf("Matched stdout text:\n%s", want) -} - -func (tt *TestCmd) matchExactOutput(want []byte) error { - buf := make([]byte, len(want)) - n := 0 - n, _ = io.ReadFull(tt.stdout, buf) - buf = buf[:n] - if n < len(want) || !bytes.Equal(buf, want) { - // Grab any additional buffered output in case of mismatch - // because it might help with debugging. - buf = append(buf, make([]byte, tt.stdout.Buffered())...) - tt.stdout.Read(buf[n:]) - // Find the mismatch position. - for i := 0; i < n; i++ { - if want[i] != buf[i] { - return fmt.Errorf("Output mismatch at ◊:\n---------------- (stdout text)\n%s◊%s\n---------------- (expected text)\n%s", - buf[:i], buf[i:n], want) - } - } - if n < len(want) { - return fmt.Errorf("Not enough output, got until ◊:\n---------------- (stdout text)\n%s\n---------------- (expected text)\n%s◊%s", - buf, want[:n], want[n:]) - } - } - return nil -} - -// ExpectRegexp expects the child process to output text matching the -// given regular expression within 5s. -// -// Note that an arbitrary amount of output may be consumed by the -// regular expression. This usually means that expect cannot be used -// after ExpectRegexp. -func (tt *TestCmd) ExpectRegexp(regex string) (*regexp.Regexp, []string) { - regex = strings.TrimPrefix(regex, "\n") - var ( - re = regexp.MustCompile(regex) - rtee = &runeTee{in: tt.stdout} - matches []int - ) - matches = re.FindReaderSubmatchIndex(rtee) - output := rtee.buf.Bytes() - if matches == nil { - tt.Fatalf("Output did not match:\n---------------- (stdout text)\n%s\n---------------- (regular expression)\n%s", - output, regex) - return re, nil - } - tt.Logf("Matched stdout text:\n%s", output) - var submatches []string - for i := 0; i < len(matches); i += 2 { - submatch := string(output[matches[i]:matches[i+1]]) - submatches = append(submatches, submatch) - } - return re, submatches -} - -// ExpectExit expects the child process to exit within 5s without -// printing any additional text on stdout. -func (tt *TestCmd) ExpectExit() { - var output []byte - output, _ = ioutil.ReadAll(tt.stdout) - tt.WaitExit() - if tt.Cleanup != nil { - tt.Cleanup() - } - if len(output) > 0 { - tt.Errorf("Unmatched stdout text:\n%s", output) - } -} - -func (tt *TestCmd) WaitExit() { - tt.Err = tt.cmd.Wait() -} - -func (tt *TestCmd) Interrupt() { - tt.Err = tt.cmd.Process.Signal(os.Interrupt) -} - -// ExitStatus exposes the process' OS exit code -// It will only return a valid value after the process has finished. -func (tt *TestCmd) ExitStatus() int { - if tt.Err != nil { - exitErr := tt.Err.(*exec.ExitError) - if exitErr != nil { - if status, ok := exitErr.Sys().(syscall.WaitStatus); ok { - return status.ExitStatus() - } - } - } - return 0 -} - -// StderrText returns any stderr output written so far. -// The returned text holds all log lines after ExpectExit has -// returned. -func (tt *TestCmd) StderrText() string { - tt.stderr.mu.Lock() - defer tt.stderr.mu.Unlock() - return tt.stderr.buf.String() -} - -func (tt *TestCmd) CloseStdin() { - tt.stdin.Close() -} - -func (tt *TestCmd) Kill() { - tt.cmd.Process.Kill() - if tt.Cleanup != nil { - tt.Cleanup() - } -} - -// testlogger logs all written lines via t.Log and also -// collects them for later inspection. -type testlogger struct { - t *testing.T - mu sync.Mutex - buf bytes.Buffer -} - -func (tl *testlogger) Write(b []byte) (n int, err error) { - lines := bytes.Split(b, []byte("\n")) - for _, line := range lines { - if len(line) > 0 { - tl.t.Logf("(stderr) %s", line) - } - } - tl.mu.Lock() - tl.buf.Write(b) - tl.mu.Unlock() - return len(b), err -} - -// runeTee collects text read through it into buf. -type runeTee struct { - in interface { - io.Reader - io.ByteReader - io.RuneReader - } - buf bytes.Buffer -} - -func (rtee *runeTee) Read(b []byte) (n int, err error) { - n, err = rtee.in.Read(b) - rtee.buf.Write(b[:n]) - return n, err -} - -func (rtee *runeTee) ReadRune() (r rune, size int, err error) { - r, size, err = rtee.in.ReadRune() - if err == nil { - rtee.buf.WriteRune(r) - } - return r, size, err -} - -func (rtee *runeTee) ReadByte() (b byte, err error) { - b, err = rtee.in.ReadByte() - if err == nil { - rtee.buf.WriteByte(b) - } - return b, err -} diff --git a/evm/go-x1/cmd/opera/launcher/accountcmd.go b/evm/go-x1/cmd/opera/launcher/accountcmd.go deleted file mode 100644 index 159a915..0000000 --- a/evm/go-x1/cmd/opera/launcher/accountcmd.go +++ /dev/null @@ -1,413 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package launcher - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/console/prompt" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "gopkg.in/urfave/cli.v1" -) - -var ( - walletCommand = cli.Command{ - Name: "wallet", - Usage: "Manage Ethereum presale wallets", - ArgsUsage: "", - Category: "ACCOUNT COMMANDS", - Description: ` - opera wallet import /path/to/my/presale.wallet - -will prompt for your password and imports your ether presale account. -It can be used non-interactively with the --password option taking a -passwordfile as argument containing the wallet password in plaintext.`, - Subcommands: []cli.Command{ - { - - Name: "import", - Usage: "Import Ethereum presale wallet", - ArgsUsage: "", - Action: utils.MigrateFlags(importWallet), - Category: "ACCOUNT COMMANDS", - Flags: []cli.Flag{ - DataDirFlag, - utils.KeyStoreDirFlag, - utils.PasswordFileFlag, - utils.LightKDFFlag, - }, - Description: ` - opera wallet [options] /path/to/my/presale.wallet - -will prompt for your password and imports your ether presale account. -It can be used non-interactively with the --password option taking a -passwordfile as argument containing the wallet password in plaintext.`, - }, - }, - } - - accountCommand = cli.Command{ - Name: "account", - Usage: "Manage accounts", - Category: "ACCOUNT COMMANDS", - Description: ` - -Manage accounts, list all existing accounts, import a private key into a new -account, create a new account or update an existing account. - -It supports interactive mode, when you are prompted for password as well as -non-interactive mode where passwords are supplied via a given password file. -Non-interactive mode is only meant for scripted use on test networks or known -safe environments. - -Make sure you remember the password you gave when creating a new account (with -either new or import). Without it you are not able to unlock your account. - -Note that exporting your key in unencrypted format is NOT supported. - -Keys are stored under /keystore. -It is safe to transfer the entire directory or the individual keys therein -between ethereum nodes by simply copying. - -Make sure you backup your keys regularly.`, - Subcommands: []cli.Command{ - { - Name: "list", - Usage: "Print summary of existing accounts", - Action: utils.MigrateFlags(accountList), - Flags: []cli.Flag{ - DataDirFlag, - utils.KeyStoreDirFlag, - }, - Description: ` -Print a short summary of all accounts`, - }, - { - Name: "new", - Usage: "Create a new account", - Action: utils.MigrateFlags(accountCreate), - Flags: []cli.Flag{ - DataDirFlag, - utils.KeyStoreDirFlag, - utils.PasswordFileFlag, - utils.LightKDFFlag, - }, - Description: ` - opera account new - -Creates a new account and prints the address. - -The account is saved in encrypted format, you are prompted for a passphrase. - -You must remember this passphrase to unlock your account in the future. - -For non-interactive use the passphrase can be specified with the --password flag: - -Note, this is meant to be used for testing only, it is a bad idea to save your -password to file or expose in any other way. -`, - }, - { - Name: "update", - Usage: "Update an existing account", - Action: utils.MigrateFlags(accountUpdate), - ArgsUsage: "
", - Flags: []cli.Flag{ - DataDirFlag, - utils.KeyStoreDirFlag, - utils.LightKDFFlag, - }, - Description: ` - opera account update
- -Update an existing account. - -The account is saved in the newest version in encrypted format, you are prompted -for a passphrase to unlock the account and another to save the updated file. - -This same command can therefore be used to migrate an account of a deprecated -format to the newest format or change the password for an account. - -For non-interactive use the passphrase can be specified with the --password flag: - - opera account update [options]
- -Since only one password can be given, only format update can be performed, -changing your password is only possible interactively. -`, - }, - { - Name: "import", - Usage: "Import a private key into a new account", - Action: utils.MigrateFlags(accountImport), - Flags: []cli.Flag{ - DataDirFlag, - utils.KeyStoreDirFlag, - utils.PasswordFileFlag, - utils.LightKDFFlag, - }, - ArgsUsage: "", - Description: ` - opera account import - -Imports an unencrypted private key from and creates a new account. -Prints the address. - -The keyfile is assumed to contain an unencrypted private key in hexadecimal format. - -The account is saved in encrypted format, you are prompted for a passphrase. - -You must remember this passphrase to unlock your account in the future. - -For non-interactive use the passphrase can be specified with the -password flag: - - opera account import [options] - -Note: -As you can directly copy your encrypted accounts to another ethereum instance, -this import mechanism is not needed when you transfer an account between -nodes. -`, - }, - }, - } -) - -func accountList(ctx *cli.Context) error { - cfg := makeAllConfigs(ctx) - stack := makeConfigNode(ctx, &cfg.Node) - var index int - for _, wallet := range stack.AccountManager().Wallets() { - for _, account := range wallet.Accounts() { - fmt.Printf("Account #%d: {%x} %s\n", index, account.Address, &account.URL) - index++ - } - } - return nil -} - -// tries unlocking the specified account a few times. -func unlockAccount(ks *keystore.KeyStore, address string, i int, passwords []string) (accounts.Account, string) { - account, err := utils.MakeAddress(ks, address) - if err != nil { - utils.Fatalf("Could not list accounts: %v", err) - } - for trials := 0; trials < 3; trials++ { - prompt := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", address, trials+1, 3) - password := getPassPhrase(prompt, false, i, passwords) - err = ks.Unlock(account, password) - if err == nil { - log.Info("Unlocked account", "address", account.Address.Hex()) - return account, password - } - if err, ok := err.(*keystore.AmbiguousAddrError); ok { - log.Info("Unlocked account", "address", account.Address.Hex()) - return ambiguousAddrRecovery(ks, err, password), password - } - if err != keystore.ErrDecrypt { - // No need to prompt again if the error is not decryption-related. - break - } - } - // All trials expended to unlock account, bail out - utils.Fatalf("Failed to unlock account %s (%v)", address, err) - - return accounts.Account{}, "" -} - -// getPassPhrase retrieves the password associated with an account, either fetched -// from a list of preloaded passphrases, or requested interactively from the user. -func getPassPhrase(msg string, confirmation bool, i int, passwords []string) string { - // If a list of passwords was supplied, retrieve from them - if len(passwords) > 0 { - if i < len(passwords) { - return passwords[i] - } - return passwords[len(passwords)-1] - } - // Otherwise prompt the user for the password - if msg != "" { - fmt.Println(msg) - } - password, err := prompt.Stdin.PromptPassword("Passphrase: ") - if err != nil { - utils.Fatalf("Failed to read passphrase: %v", err) - } - if confirmation { - confirm, err := prompt.Stdin.PromptPassword("Repeat passphrase: ") - if err != nil { - utils.Fatalf("Failed to read passphrase confirmation: %v", err) - } - if password != confirm { - utils.Fatalf("Passphrases do not match") - } - } - return password -} - -func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrError, auth string) accounts.Account { - fmt.Printf("Multiple key files exist for address %x:\n", err.Addr) - for _, a := range err.Matches { - fmt.Println(" ", a.URL) - } - fmt.Println("Testing your passphrase against all of them...") - var match *accounts.Account - for _, a := range err.Matches { - if err := ks.Unlock(a, auth); err == nil { - match = &a - break - } - } - if match == nil { - utils.Fatalf("None of the listed files could be unlocked.") - } - fmt.Printf("Your passphrase unlocked %s\n", match.URL) - fmt.Println("In order to avoid this warning, you need to remove the following duplicate key files:") - for _, a := range err.Matches { - if a != *match { - fmt.Println(" ", a.URL) - } - } - return *match -} - -// accountCreate creates a new account into the keystore defined by the CLI flags. -func accountCreate(ctx *cli.Context) error { - cfg := makeAllConfigs(ctx) - utils.SetNodeConfig(ctx, &cfg.Node) - scryptN, scryptP, keydir, err := cfg.Node.AccountConfig() - - if err != nil { - utils.Fatalf("Failed to read configuration: %v", err) - } - - password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) - - account, err := keystore.StoreKey(keydir, password, scryptN, scryptP) - - if err != nil { - utils.Fatalf("Failed to create account: %v", err) - } - fmt.Printf("\nYour new key was generated\n\n") - fmt.Printf("Public address of the key: %s\n", account.Address.Hex()) - fmt.Printf("Path of the secret key file: %s\n\n", account.URL.Path) - fmt.Printf("- You can share your public address with anyone. Others need it to interact with you.\n") - fmt.Printf("- You must NEVER share the secret key with anyone! The key controls access to your funds!\n") - fmt.Printf("- You must BACKUP your key file! Without the key, it's impossible to access account funds!\n") - fmt.Printf("- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!\n\n") - return nil -} - -// accountUpdate transitions an account from a previous format to the current -// one, also providing the possibility to change the pass-phrase. -func accountUpdate(ctx *cli.Context) error { - if len(ctx.Args()) == 0 { - utils.Fatalf("No accounts specified to update") - } - - cfg := makeAllConfigs(ctx) - stack := makeConfigNode(ctx, &cfg.Node) - ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) - - for _, addr := range ctx.Args() { - account, oldPassword := unlockAccount(ks, addr, 0, nil) - newPassword := getPassPhrase("Please give a new password. Do not forget this password.", true, 0, nil) - if err := ks.Update(account, oldPassword, newPassword); err != nil { - utils.Fatalf("Could not update the account: %v", err) - } - } - return nil -} - -func importWallet(ctx *cli.Context) error { - keyfile := ctx.Args().First() - if len(keyfile) == 0 { - utils.Fatalf("keyfile must be given as argument") - } - keyJSON, err := ioutil.ReadFile(keyfile) - if err != nil { - utils.Fatalf("Could not read wallet file: %v", err) - } - - cfg := makeAllConfigs(ctx) - stack := makeConfigNode(ctx, &cfg.Node) - passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx)) - - ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) - acct, err := ks.ImportPreSaleKey(keyJSON, passphrase) - if err != nil { - utils.Fatalf("%v", err) - } - fmt.Printf("Address: {%x}\n", acct.Address) - return nil -} - -func accountImport(ctx *cli.Context) error { - keyfile := ctx.Args().First() - if len(keyfile) == 0 { - utils.Fatalf("keyfile must be given as argument") - } - key, err := crypto.LoadECDSA(keyfile) - if err != nil { - utils.Fatalf("Failed to load the private key: %v", err) - } - - cfg := makeAllConfigs(ctx) - stack := makeConfigNode(ctx, &cfg.Node) - passphrase := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) - - ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) - acct, err := ks.ImportECDSA(key, passphrase) - if err != nil { - utils.Fatalf("Could not create the account: %v", err) - } - fmt.Printf("Address: {%x}\n", acct.Address) - return nil -} - -func FindAccountKeypath(addr common.Address, keydir string) (keypath string, err error) { - addrStr := strings.ToLower(addr.String())[2:] - // find key path - err = filepath.Walk(keydir, func(walk string, info os.FileInfo, err error) error { - if err != nil { - return err - } - _, filename := filepath.Split(walk) - if strings.Contains(strings.ToLower(filename), addrStr) { - keypath = walk - return filepath.SkipDir - } - return nil - }) - if err != nil { - return keypath, err - } - if len(keypath) == 0 { - return keypath, errors.New("account not found") - } - return keypath, nil -} diff --git a/evm/go-x1/cmd/opera/launcher/accountcmd_test.go b/evm/go-x1/cmd/opera/launcher/accountcmd_test.go deleted file mode 100644 index b413e14..0000000 --- a/evm/go-x1/cmd/opera/launcher/accountcmd_test.go +++ /dev/null @@ -1,301 +0,0 @@ -package launcher - -import ( - "io/ioutil" - "path/filepath" - "runtime" - "strings" - "testing" - - "github.com/cespare/cp" -) - -// These tests are 'smoke tests' for the account related -// subcommands and flags. -// -// For most tests, the test files from package accounts -// are copied into a temporary keystore directory. - -func tmpDatadirWithKeystore(t *testing.T) string { - datadir := tmpdir(t) - keystore := filepath.Join(datadir, "keystore") - source := filepath.Join("testdata", "keystore") - if err := cp.CopyAll(keystore, source); err != nil { - t.Fatal(err) - } - return datadir -} - -func TestAccountListEmpty(t *testing.T) { - cli := exec(t, "--fakenet", "0/1", "account", "list") - cli.ExpectExit() -} - -func TestAccountList(t *testing.T) { - datadir := tmpDatadirWithKeystore(t) - cli := exec(t, "--fakenet", "0/1", "account", "list", "--datadir", datadir) - - if runtime.GOOS == "windows" { - cli.Expect(` -Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 -Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}\keystore\aaa -Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\keystore\zzz -`) - } else { - cli.Expect(` -Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 -Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa -Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/keystore/zzz -`) - } - - cli.ExpectExit() -} - -func TestAccountNew(t *testing.T) { - cli := exec(t, "--fakenet", "0/1", "account", "new", "--lightkdf") - - cli.Expect(` -Your new account is locked with a password. Please give a password. Do not forget this password. -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "foobar"}} -Repeat passphrase: {{.InputLine "foobar"}} - -Your new key was generated -`) - cli.ExpectRegexp(` -Public address of the key: 0x[0-9a-fA-F]{40} -Path of the secret key file: .*UTC--.+--[0-9a-f]{40} - -- You can share your public address with anyone. Others need it to interact with you. -- You must NEVER share the secret key with anyone! The key controls access to your funds! -- You must BACKUP your key file! Without the key, it's impossible to access account funds! -- You must REMEMBER your password! Without the password, it's impossible to decrypt the key! -`) - - cli.ExpectExit() -} - -func TestAccountNewBadRepeat(t *testing.T) { - cli := exec(t, "--fakenet", "0/1", "account", "new", "--lightkdf") - - cli.Expect(` -Your new account is locked with a password. Please give a password. Do not forget this password. -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "something"}} -Repeat passphrase: {{.InputLine "something else"}} -Fatal: Passphrases do not match -`) - cli.ExpectExit() -} - -func TestAccountUpdate(t *testing.T) { - datadir := tmpDatadirWithKeystore(t) - cli := exec(t, "--fakenet", "0/1", "account", "update", - "--datadir", datadir, "--lightkdf", - "f466859ead1932d743d622cb74fc058882e8648a") - defer cli.ExpectExit() - cli.Expect(` -Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "foobar"}} -Please give a new password. Do not forget this password. -Passphrase: {{.InputLine "foobar2"}} -Repeat passphrase: {{.InputLine "foobar2"}} -`) -} - -func TestWalletImport(t *testing.T) { - cli := exec(t, "--fakenet", "0/1", "wallet", "import", "--lightkdf", "testdata/guswallet.json") - - cli.Expect(` -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "foo"}} -Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f} -`) - - files, err := ioutil.ReadDir(filepath.Join(cli.Datadir, "keystore")) - if len(files) != 1 { - t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err) - } - - cli.ExpectExit() -} - -func TestWalletImportBadPassword(t *testing.T) { - cli := exec(t, "--fakenet", "0/1", "wallet", "import", "--lightkdf", "testdata/guswallet.json") - - cli.Expect(` -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "wrong"}} -Fatal: could not decrypt key with given password -`) - cli.ExpectExit() -} - -func TestUnlockFlag(t *testing.T) { - datadir := tmpDatadirWithKeystore(t) - cli := exec(t, - "--fakenet", "0/1", "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", - "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", - "js", "testdata/empty.js") - - cli.Expect(` -Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "foobar"}} -`) - cli.ExpectExit() - - wantMessages := []string{ - "Unlocked account", - "=0xf466859eAD1932D743d622CB74FC058882E8648A", - } - for _, m := range wantMessages { - if !strings.Contains(cli.StderrText(), m) { - t.Errorf("stderr text does not contain %q", m) - } - } -} - -func TestUnlockFlagWrongPassword(t *testing.T) { - datadir := tmpDatadirWithKeystore(t) - cli := exec(t, - "--fakenet", "0/1", "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", - "--unlock", "f466859ead1932d743d622cb74fc058882e8648a") - - cli.Expect(` -Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "wrong1"}} -Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3 -Passphrase: {{.InputLine "wrong2"}} -Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3 -Passphrase: {{.InputLine "wrong3"}} -Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given password) -`) - cli.ExpectExit() -} - -// https://github.com/ethereum/go-ethereum/issues/1785 -func TestUnlockFlagMultiIndex(t *testing.T) { - datadir := tmpDatadirWithKeystore(t) - cli := exec(t, - "--fakenet", "0/1", "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", - "--unlock", "0,2", - "js", "testdata/empty.js") - - cli.Expect(` -Unlocking account 0 | Attempt 1/3 -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "foobar"}} -Unlocking account 2 | Attempt 1/3 -Passphrase: {{.InputLine "foobar"}} -`) - cli.ExpectExit() - - wantMessages := []string{ - "Unlocked account", - "=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8", - "=0x289d485D9771714CCe91D3393D764E1311907ACc", - } - for _, m := range wantMessages { - if !strings.Contains(cli.StderrText(), m) { - t.Errorf("stderr text does not contain %q", m) - } - } -} - -func TestUnlockFlagPasswordFile(t *testing.T) { - datadir := tmpDatadirWithKeystore(t) - cli := exec(t, - "--fakenet", "0/1", "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", - "--password", "testdata/passwords.txt", "--unlock", "0,2", - "js", "testdata/empty.js") - - cli.ExpectExit() - - wantMessages := []string{ - "Unlocked account", - "=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8", - "=0x289d485D9771714CCe91D3393D764E1311907ACc", - } - for _, m := range wantMessages { - if !strings.Contains(cli.StderrText(), m) { - t.Errorf("stderr text does not contain %q", m) - } - } -} - -func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) { - datadir := tmpDatadirWithKeystore(t) - cli := exec(t, - "--fakenet", "0/1", "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", - "--password", "testdata/wrong-passwords.txt", "--unlock", "0,2") - - cli.Expect(` -Fatal: Failed to unlock account 0 (could not decrypt key with given password) -`) - cli.ExpectExit() -} - -func TestUnlockFlagAmbiguous(t *testing.T) { - store := filepath.Join("testdata", "dupes") - cli := exec(t, - "--fakenet", "0/1", "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", - "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", - "js", "testdata/empty.js") - - // Helper for the expect template, returns absolute keystore path. - cli.SetTemplateFunc("keypath", func(file string) string { - abs, _ := filepath.Abs(filepath.Join(store, file)) - return abs - }) - cli.Expect(` -Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "foobar"}} -Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a: - keystore://{{keypath "1"}} - keystore://{{keypath "2"}} -Testing your passphrase against all of them... -Your passphrase unlocked keystore://{{keypath "1"}} -In order to avoid this warning, you need to remove the following duplicate key files: - keystore://{{keypath "2"}} -`) - cli.ExpectExit() - - wantMessages := []string{ - "Unlocked account", - "=0xf466859eAD1932D743d622CB74FC058882E8648A", - } - for _, m := range wantMessages { - if !strings.Contains(cli.StderrText(), m) { - t.Errorf("stderr text does not contain %q", m) - } - } -} - -func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) { - store := filepath.Join("testdata", "dupes") - cli := exec(t, - "--fakenet", "0/1", "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", - "--unlock", "f466859ead1932d743d622cb74fc058882e8648a") - - // Helper for the expect template, returns absolute keystore path. - cli.SetTemplateFunc("keypath", func(file string) string { - abs, _ := filepath.Abs(filepath.Join(store, file)) - return abs - }) - cli.Expect(` -Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 -!! Unsupported terminal, password will be echoed. -Passphrase: {{.InputLine "wrong"}} -Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a: - keystore://{{keypath "1"}} - keystore://{{keypath "2"}} -Testing your passphrase against all of them... -Fatal: None of the listed files could be unlocked. -`) - cli.ExpectExit() -} diff --git a/evm/go-x1/cmd/opera/launcher/chaincmd.go b/evm/go-x1/cmd/opera/launcher/chaincmd.go deleted file mode 100644 index 00070b7..0000000 --- a/evm/go-x1/cmd/opera/launcher/chaincmd.go +++ /dev/null @@ -1,144 +0,0 @@ -package launcher - -import ( - "github.com/ethereum/go-ethereum/cmd/utils" - "gopkg.in/urfave/cli.v1" -) - -var ( - EvmExportMode = cli.StringFlag{ - Name: "export.evm.mode", - Usage: `EVM export mode ("full" or "ext-mpt" or "mpt")`, - Value: "mpt", - } - EvmExportExclude = cli.StringFlag{ - Name: "export.evm.exclude", - Usage: `DB of EVM keys to exclude from genesis`, - } - GenesisExportSections = cli.StringFlag{ - Name: "export.sections", - Usage: `Genesis sections to export separated by comma (e.g. "brs-1" or "ers" or "evm-2")`, - Value: "brs,ers,evm", - } - importCommand = cli.Command{ - Name: "import", - Usage: "Import a blockchain file", - ArgsUsage: " ( ... ) [check=false]", - Category: "MISCELLANEOUS COMMANDS", - Description: ` - opera import events - -The import command imports events from an RLP-encoded files. -Events are fully verified by default, unless overridden by check=false flag.`, - - Subcommands: []cli.Command{ - { - Action: utils.MigrateFlags(importEvents), - Name: "events", - Usage: "Import blockchain events", - ArgsUsage: " ( ... )", - Flags: []cli.Flag{ - DataDirFlag, - }, - Description: ` -The import command imports events from RLP-encoded files. -Events are fully verified by default, unless overridden by --check=false flag.`, - }, - { - Action: utils.MigrateFlags(importEvm), - Name: "evm", - Usage: "Import EVM storage", - ArgsUsage: " ( ... )", - Flags: []cli.Flag{ - DataDirFlag, - }, - Description: ` - opera import evm - -The import command imports EVM storage (trie nodes, code, preimages) from files.`, - }, - }, - } - exportCommand = cli.Command{ - Name: "export", - Usage: "Export blockchain", - Category: "MISCELLANEOUS COMMANDS", - - Subcommands: []cli.Command{ - { - Name: "events", - Usage: "Export blockchain events", - ArgsUsage: " [ ]", - Action: utils.MigrateFlags(exportEvents), - Flags: []cli.Flag{ - DataDirFlag, - }, - Description: ` - opera export events - -Requires a first argument of the file to write to. -Optional second and third arguments control the first and -last epoch to write. If the file ends with .gz, the output will -be gzipped -`, - }, - { - Name: "genesis", - Usage: "Export current state into a genesis file", - ArgsUsage: " [ ] [--export.evm.mode=MODE --export.evm.exclude=DB_PATH --export.sections=A,B,C]", - Action: utils.MigrateFlags(exportGenesis), - Flags: []cli.Flag{ - DataDirFlag, - EvmExportMode, - EvmExportExclude, - GenesisExportSections, - }, - Description: ` - opera export genesis - -Export current state into a genesis file. -Requires a first argument of the file to write to. -Optional second and third arguments control the first and -last epoch to write. -Pass dry-run instead of filename for calculation of hashes without exporting data. -EVM export mode is configured with --export.evm.mode. -`, - }, - { - Name: "evm-keys", - Usage: "Export EVM node keys", - ArgsUsage: "", - Action: utils.MigrateFlags(exportEvmKeys), - Flags: []cli.Flag{ - DataDirFlag, - }, - Description: ` - opera export evm-keys - -Requires a first argument of the DB directory to write to. -`, - }, - }, - } - checkCommand = cli.Command{ - Name: "check", - Usage: "Check blockchain", - Category: "MISCELLANEOUS COMMANDS", - - Subcommands: []cli.Command{ - { - Name: "evm", - Usage: "Check EVM storage", - Action: utils.MigrateFlags(checkEvm), - Flags: []cli.Flag{ - DataDirFlag, - }, - Description: ` - opera check evm - -Checks EVM storage roots and code hashes -`, - }, - }, - } -) diff --git a/evm/go-x1/cmd/opera/launcher/check.go b/evm/go-x1/cmd/opera/launcher/check.go deleted file mode 100644 index 5322c58..0000000 --- a/evm/go-x1/cmd/opera/launcher/check.go +++ /dev/null @@ -1,67 +0,0 @@ -package launcher - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/inter" -) - -func checkEvm(ctx *cli.Context) error { - if len(ctx.Args()) != 0 { - utils.Fatalf("This command doesn't require an argument.") - } - - cfg := makeAllConfigs(ctx) - - rawDbs := makeDirectDBsProducer(cfg) - gdb := makeGossipStore(rawDbs, cfg) - defer gdb.Close() - evms := gdb.EvmStore() - - start, reported := time.Now(), time.Now() - - var prevPoint idx.Block - var prevIndex idx.Block - checkBlocks := func(stateOK func(root common.Hash) (bool, error)) { - var ( - lastIdx = gdb.GetLatestBlockIndex() - prevPointRootExist bool - ) - gdb.ForEachBlock(func(index idx.Block, block *inter.Block) { - prevIndex = index - found, err := stateOK(common.Hash(block.Root)) - if found != prevPointRootExist { - if index > 0 && found { - log.Warn("EVM history is pruned", "fromBlock", prevPoint, "toBlock", index-1) - } - prevPointRootExist = found - prevPoint = index - } - if index == lastIdx && !found { - log.Crit("State trie for the latest block is not found", "block", index) - } - if !found { - return - } - if err != nil { - log.Crit("State trie error", "err", err, "block", index) - } - if time.Since(reported) >= statsReportLimit { - log.Info("Checking presence of every node", "last", index, "pruned", !prevPointRootExist, "elapsed", common.PrettyDuration(time.Since(start))) - reported = time.Now() - } - }) - } - - if err := evms.CheckEvm(checkBlocks, true); err != nil { - return err - } - log.Info("EVM storage is verified", "last", prevIndex, "elapsed", common.PrettyDuration(time.Since(start))) - return nil -} diff --git a/evm/go-x1/cmd/opera/launcher/config.go b/evm/go-x1/cmd/opera/launcher/config.go deleted file mode 100644 index 5b97e36..0000000 --- a/evm/go-x1/cmd/opera/launcher/config.go +++ /dev/null @@ -1,611 +0,0 @@ -package launcher - -import ( - "bufio" - "errors" - "fmt" - "math/big" - "os" - "path" - "path/filepath" - "reflect" - "strings" - - "github.com/Fantom-foundation/go-opera/integration/maketestnetgenesis" - "github.com/Fantom-foundation/lachesis-base/abft" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/params" - "github.com/naoina/toml" - "github.com/syndtr/goleveldb/leveldb/opt" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/gossip/gasprice" - "github.com/Fantom-foundation/go-opera/integration" - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/opera/genesisstore" - futils "github.com/Fantom-foundation/go-opera/utils" - "github.com/Fantom-foundation/go-opera/utils/memory" - "github.com/Fantom-foundation/go-opera/vecmt" -) - -var ( - dumpConfigCommand = cli.Command{ - Action: utils.MigrateFlags(dumpConfig), - Name: "dumpconfig", - Usage: "Show configuration values", - ArgsUsage: "", - Flags: append(nodeFlags, testFlags...), - Category: "MISCELLANEOUS COMMANDS", - Description: `The dumpconfig command shows configuration values.`, - } - checkConfigCommand = cli.Command{ - Action: utils.MigrateFlags(checkConfig), - Name: "checkconfig", - Usage: "Checks configuration file", - ArgsUsage: "", - Flags: append(nodeFlags, testFlags...), - Category: "MISCELLANEOUS COMMANDS", - Description: `The checkconfig checks configuration file.`, - } - - configFileFlag = cli.StringFlag{ - Name: "config", - Usage: "TOML configuration file", - } - - // DataDirFlag defines directory to store Lachesis state and user's wallets - DataDirFlag = utils.DirectoryFlag{ - Name: "datadir", - Usage: "Data directory for the databases and keystore", - Value: utils.DirectoryString(DefaultDataDir()), - } - - CacheFlag = cli.IntFlag{ - Name: "cache", - Usage: "Megabytes of memory allocated to internal caching", - Value: DefaultCacheSize, - } - // GenesisFlag specifies network genesis configuration - GenesisFlag = cli.StringFlag{ - Name: "genesis", - Usage: "'path to genesis file' - sets the network genesis configuration.", - } - ExperimentalGenesisFlag = cli.BoolFlag{ - Name: "genesis.allowExperimental", - Usage: "Allow to use experimental genesis file.", - } - - RPCGlobalGasCapFlag = cli.Uint64Flag{ - Name: "rpc.gascap", - Usage: "Sets a cap on gas that can be used in ftm_call/estimateGas (0=infinite)", - Value: gossip.DefaultConfig(cachescale.Identity).RPCGasCap, - } - RPCGlobalEVMTimeoutFlag = &cli.DurationFlag{ - Name: "rpc.evmtimeout", - Usage: "Sets a timeout used for eth_call (0=infinite)", - Value: gossip.DefaultConfig(cachescale.Identity).RPCEVMTimeout, - } - RPCGlobalTxFeeCapFlag = cli.Float64Flag{ - Name: "rpc.txfeecap", - Usage: "Sets a cap on transaction fee (in FTM) that can be sent via the RPC APIs (0 = no cap)", - Value: gossip.DefaultConfig(cachescale.Identity).RPCTxFeeCap, - } - RPCGlobalTimeoutFlag = cli.DurationFlag{ - Name: "rpc.timeout", - Usage: "Time limit for RPC calls execution", - Value: gossip.DefaultConfig(cachescale.Identity).RPCTimeout, - } - - SyncModeFlag = cli.StringFlag{ - Name: "syncmode", - Usage: `Blockchain sync mode ("full" or "snap")`, - Value: "snap", - } - - GCModeFlag = cli.StringFlag{ - Name: "gcmode", - Usage: `Blockchain garbage collection mode ("light", "full", "archive")`, - Value: "archive", - } - - ExitWhenAgeFlag = cli.DurationFlag{ - Name: "exitwhensynced.age", - Usage: "Exits after synchronisation reaches the required age", - } - ExitWhenEpochFlag = cli.Uint64Flag{ - Name: "exitwhensynced.epoch", - Usage: "Exits after synchronisation reaches the required epoch", - } - - DBMigrationModeFlag = cli.StringFlag{ - Name: "db.migration.mode", - Usage: "MultiDB migration mode ('reformat' or 'rebuild')", - } - DBPresetFlag = cli.StringFlag{ - Name: "db.preset", - Usage: "DBs layout preset ('pbl-1' or 'ldb-1' or 'legacy-ldb' or 'legacy-pbl')", - Value: "pbl-1", - } -) - -type GenesisTemplate struct { - Name string - Header genesis.Header - Hashes genesis.Hashes -} - -const ( - // DefaultCacheSize is calculated as memory consumption in a worst case scenario with default configuration - // Average memory consumption might be 3-5 times lower than the maximum - DefaultCacheSize = 3600 - ConstantCacheSize = 400 -) - -// These settings ensure that TOML keys use the same names as Go struct fields. -var tomlSettings = toml.Config{ - NormFieldName: func(rt reflect.Type, key string) string { - return key - }, - FieldToKey: func(rt reflect.Type, field string) string { - return field - }, - MissingField: func(rt reflect.Type, field string) error { - return fmt.Errorf("field '%s' is not defined in %s", field, rt.String()) - }, -} - -type config struct { - Node node.Config - Opera gossip.Config - Emitter emitter.Config - TxPool evmcore.TxPoolConfig - OperaStore gossip.StoreConfig - Lachesis abft.Config - LachesisStore abft.StoreConfig - VectorClock vecmt.IndexConfig - DBs integration.DBsConfig -} - -func (c *config) AppConfigs() integration.Configs { - return integration.Configs{ - Opera: c.Opera, - OperaStore: c.OperaStore, - Lachesis: c.Lachesis, - LachesisStore: c.LachesisStore, - VectorClock: c.VectorClock, - DBs: c.DBs, - } -} - -func loadAllConfigs(file string, cfg *config) error { - f, err := os.Open(file) - if err != nil { - return err - } - defer f.Close() - - err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(cfg) - // Add file name to errors that have a line number. - if _, ok := err.(*toml.LineError); ok { - err = errors.New(file + ", " + err.Error()) - } - if err != nil { - return errors.New(fmt.Sprintf("TOML config file error: %v.\n"+ - "Use 'dumpconfig' command to get an example config file.\n"+ - "If node was recently upgraded and a previous network config file is used, then check updates for the config file.", err)) - } - return err -} - -func mayGetGenesisStore(ctx *cli.Context) *genesisstore.Store { - switch { - case ctx.GlobalIsSet(TestnetFlag.Name): - return maketestnetgenesis.TestnetGenesisStore() - case ctx.GlobalIsSet(FakeNetFlag.Name): - _, num, err := parseFakeGen(ctx.GlobalString(FakeNetFlag.Name)) - if err != nil { - log.Crit("Invalid flag", "flag", FakeNetFlag.Name, "err", err) - } - return makefakegenesis.FakeGenesisStore(num, futils.ToFtm(1000000000), futils.ToFtm(5000000)) - case ctx.GlobalIsSet(GenesisFlag.Name): - genesisPath := ctx.GlobalString(GenesisFlag.Name) - - f, err := os.Open(genesisPath) - if err != nil { - utils.Fatalf("Failed to open genesis file: %v", err) - } - genesisStore, genesisHashes, err := genesisstore.OpenGenesisStore(f) - if err != nil { - utils.Fatalf("Failed to read genesis file: %v", err) - } - - // check if it's a trusted preset - { - g := genesisStore.Genesis() - gHeader := genesis.Header{ - GenesisID: g.GenesisID, - NetworkID: g.NetworkID, - NetworkName: g.NetworkName, - } - for _, allowed := range AllowedOperaGenesis { - if allowed.Hashes.Equal(genesisHashes) && allowed.Header.Equal(gHeader) { - log.Info("Genesis file is a known preset", "name", allowed.Name) - goto notExperimental - } - } - if ctx.GlobalBool(ExperimentalGenesisFlag.Name) { - log.Warn("Genesis file doesn't refer to any trusted preset") - } else { - utils.Fatalf("Genesis file doesn't refer to any trusted preset. Enable experimental genesis with --genesis.allowExperimental") - } - notExperimental: - } - return genesisStore - } - return nil -} - -func setBootnodes(ctx *cli.Context, urls []string, cfg *node.Config) { - cfg.P2P.BootstrapNodesV5 = []*enode.Node{} - for _, url := range urls { - if url != "" { - node, err := enode.Parse(enode.ValidSchemes, url) - if err != nil { - log.Error("Bootstrap URL invalid", "enode", url, "err", err) - continue - } - cfg.P2P.BootstrapNodesV5 = append(cfg.P2P.BootstrapNodesV5, node) - } - } - cfg.P2P.BootstrapNodes = cfg.P2P.BootstrapNodesV5 - cfg.P2P.TrustedNodes = cfg.P2P.BootstrapNodesV5 -} - -func setDataDir(ctx *cli.Context, cfg *node.Config) { - defaultDataDir := DefaultDataDir() - - switch { - case ctx.GlobalIsSet(DataDirFlag.Name): - cfg.DataDir = ctx.GlobalString(DataDirFlag.Name) - case ctx.GlobalIsSet(FakeNetFlag.Name): - _, num, err := parseFakeGen(ctx.GlobalString(FakeNetFlag.Name)) - if err != nil { - log.Crit("Invalid flag", "flag", FakeNetFlag.Name, "err", err) - } - cfg.DataDir = filepath.Join(defaultDataDir, fmt.Sprintf("fakenet-%d", num)) - } -} - -func setGPO(ctx *cli.Context, cfg *gasprice.Config) {} - -func setTxPool(ctx *cli.Context, cfg *evmcore.TxPoolConfig) { - if ctx.GlobalIsSet(utils.TxPoolLocalsFlag.Name) { - locals := strings.Split(ctx.GlobalString(utils.TxPoolLocalsFlag.Name), ",") - for _, account := range locals { - if trimmed := strings.TrimSpace(account); !common.IsHexAddress(trimmed) { - utils.Fatalf("Invalid account in --txpool.locals: %s", trimmed) - } else { - cfg.Locals = append(cfg.Locals, common.HexToAddress(account)) - } - } - } - if ctx.GlobalIsSet(utils.TxPoolNoLocalsFlag.Name) { - cfg.NoLocals = ctx.GlobalBool(utils.TxPoolNoLocalsFlag.Name) - } - if ctx.GlobalIsSet(utils.TxPoolJournalFlag.Name) { - cfg.Journal = ctx.GlobalString(utils.TxPoolJournalFlag.Name) - } - if ctx.GlobalIsSet(utils.TxPoolRejournalFlag.Name) { - cfg.Rejournal = ctx.GlobalDuration(utils.TxPoolRejournalFlag.Name) - } - if ctx.GlobalIsSet(utils.TxPoolPriceLimitFlag.Name) { - cfg.PriceLimit = ctx.GlobalUint64(utils.TxPoolPriceLimitFlag.Name) - } - if ctx.GlobalIsSet(utils.TxPoolPriceBumpFlag.Name) { - cfg.PriceBump = ctx.GlobalUint64(utils.TxPoolPriceBumpFlag.Name) - } - if ctx.GlobalIsSet(utils.TxPoolAccountSlotsFlag.Name) { - cfg.AccountSlots = ctx.GlobalUint64(utils.TxPoolAccountSlotsFlag.Name) - } - if ctx.GlobalIsSet(utils.TxPoolGlobalSlotsFlag.Name) { - cfg.GlobalSlots = ctx.GlobalUint64(utils.TxPoolGlobalSlotsFlag.Name) - } - if ctx.GlobalIsSet(utils.TxPoolAccountQueueFlag.Name) { - cfg.AccountQueue = ctx.GlobalUint64(utils.TxPoolAccountQueueFlag.Name) - } - if ctx.GlobalIsSet(utils.TxPoolGlobalQueueFlag.Name) { - cfg.GlobalQueue = ctx.GlobalUint64(utils.TxPoolGlobalQueueFlag.Name) - } - if ctx.GlobalIsSet(utils.TxPoolLifetimeFlag.Name) { - cfg.Lifetime = ctx.GlobalDuration(utils.TxPoolLifetimeFlag.Name) - } -} - -func gossipConfigWithFlags(ctx *cli.Context, src gossip.Config) (gossip.Config, error) { - cfg := src - - setGPO(ctx, &cfg.GPO) - - if ctx.GlobalIsSet(RPCGlobalGasCapFlag.Name) { - cfg.RPCGasCap = ctx.GlobalUint64(RPCGlobalGasCapFlag.Name) - } - if ctx.GlobalIsSet(RPCGlobalEVMTimeoutFlag.Name) { - cfg.RPCEVMTimeout = ctx.GlobalDuration(RPCGlobalEVMTimeoutFlag.Name) - } - if ctx.GlobalIsSet(RPCGlobalTxFeeCapFlag.Name) { - cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCapFlag.Name) - } - if ctx.GlobalIsSet(RPCGlobalTimeoutFlag.Name) { - cfg.RPCTimeout = ctx.GlobalDuration(RPCGlobalTimeoutFlag.Name) - } - if ctx.GlobalIsSet(SyncModeFlag.Name) { - if syncmode := ctx.GlobalString(SyncModeFlag.Name); syncmode != "full" && syncmode != "snap" { - utils.Fatalf("--%s must be either 'full' or 'snap'", SyncModeFlag.Name) - } - cfg.AllowSnapsync = ctx.GlobalString(SyncModeFlag.Name) == "snap" - } - - return cfg, nil -} - -func gossipStoreConfigWithFlags(ctx *cli.Context, src gossip.StoreConfig) (gossip.StoreConfig, error) { - cfg := src - if ctx.GlobalIsSet(utils.GCModeFlag.Name) { - if gcmode := ctx.GlobalString(utils.GCModeFlag.Name); gcmode != "light" && gcmode != "full" && gcmode != "archive" { - utils.Fatalf("--%s must be 'light', 'full' or 'archive'", GCModeFlag.Name) - } - cfg.EVM.Cache.TrieDirtyDisabled = ctx.GlobalString(utils.GCModeFlag.Name) == "archive" - cfg.EVM.Cache.GreedyGC = ctx.GlobalString(utils.GCModeFlag.Name) == "full" - } - return cfg, nil -} - -func setDBConfig(ctx *cli.Context, cfg integration.DBsConfig, cacheRatio cachescale.Func) integration.DBsConfig { - if ctx.GlobalIsSet(DBPresetFlag.Name) { - preset := ctx.GlobalString(DBPresetFlag.Name) - cfg = setDBConfigStr(cfg, cacheRatio, preset) - } - if ctx.GlobalIsSet(DBMigrationModeFlag.Name) { - cfg.MigrationMode = ctx.GlobalString(DBMigrationModeFlag.Name) - } - return cfg -} - -func setDBConfigStr(cfg integration.DBsConfig, cacheRatio cachescale.Func, preset string) integration.DBsConfig { - switch preset { - case "pbl-1": - cfg = integration.Pbl1DBsConfig(cacheRatio.U64, uint64(utils.MakeDatabaseHandles())) - case "ldb-1": - cfg = integration.Ldb1DBsConfig(cacheRatio.U64, uint64(utils.MakeDatabaseHandles())) - case "legacy-ldb": - cfg = integration.LdbLegacyDBsConfig(cacheRatio.U64, uint64(utils.MakeDatabaseHandles())) - case "legacy-pbl": - cfg = integration.PblLegacyDBsConfig(cacheRatio.U64, uint64(utils.MakeDatabaseHandles())) - default: - utils.Fatalf("--%s must be 'pbl-1', 'ldb-1', 'legacy-pbl' or 'legacy-ldb'", DBPresetFlag.Name) - } - // sanity check - if preset != reversePresetName(cfg.Routing) { - log.Error("Preset name cannot be reversed") - } - return cfg -} - -func reversePresetName(cfg integration.RoutingConfig) string { - pbl1 := integration.Pbl1RoutingConfig() - ldb1 := integration.Ldb1RoutingConfig() - ldbLegacy := integration.LdbLegacyRoutingConfig() - pblLegacy := integration.PblLegacyRoutingConfig() - if cfg.Equal(pbl1) { - return "pbl-1" - } - if cfg.Equal(ldb1) { - return "ldb-1" - } - if cfg.Equal(ldbLegacy) { - return "legacy-ldb" - } - if cfg.Equal(pblLegacy) { - return "legacy-pbl" - } - return "" -} - -func memorizeDBPreset(cfg *config) { - preset := reversePresetName(cfg.DBs.Routing) - pPath := path.Join(cfg.Node.DataDir, "chaindata", "preset") - if len(preset) != 0 { - futils.FilePut(pPath, []byte(preset), true) - } else { - _ = os.Remove(pPath) - } -} - -func setDBConfigDefault(cfg config, cacheRatio cachescale.Func) config { - if len(cfg.DBs.Routing.Table) == 0 && len(cfg.DBs.GenesisCache.Table) == 0 && len(cfg.DBs.RuntimeCache.Table) == 0 { - // Substitute memorized db preset from datadir, unless already set - datadirPreset := futils.FileGet(path.Join(cfg.Node.DataDir, "chaindata", "preset")) - if len(datadirPreset) != 0 { - cfg.DBs = setDBConfigStr(cfg.DBs, cacheRatio, string(datadirPreset)) - } - } - // apply default for DB config if it wasn't touched by config file or flags, and there's no datadir's default value - dbDefault := integration.DefaultDBsConfig(cacheRatio.U64, uint64(utils.MakeDatabaseHandles())) - if len(cfg.DBs.Routing.Table) == 0 { - cfg.DBs.Routing = dbDefault.Routing - } - if len(cfg.DBs.GenesisCache.Table) == 0 { - cfg.DBs.GenesisCache = dbDefault.GenesisCache - } - if len(cfg.DBs.RuntimeCache.Table) == 0 { - cfg.DBs.RuntimeCache = dbDefault.RuntimeCache - } - return cfg -} - -func nodeConfigWithFlags(ctx *cli.Context, cfg node.Config) node.Config { - utils.SetNodeConfig(ctx, &cfg) - - setDataDir(ctx, &cfg) - return cfg -} - -func cacheScaler(ctx *cli.Context) cachescale.Func { - targetCache := ctx.GlobalInt(CacheFlag.Name) - baseSize := DefaultCacheSize - totalMemory := int(memory.TotalMemory() / opt.MiB) - maxCache := totalMemory * 3 / 5 - if maxCache < baseSize { - maxCache = baseSize - } - if !ctx.GlobalIsSet(CacheFlag.Name) { - recommendedCache := totalMemory / 2 - if recommendedCache > baseSize { - log.Warn(fmt.Sprintf("Please add '--%s %d' flag to allocate more cache for X1. Total memory is %d MB.", CacheFlag.Name, recommendedCache, totalMemory)) - } - return cachescale.Identity - } - if targetCache < baseSize { - log.Crit("Invalid flag", "flag", CacheFlag.Name, "err", fmt.Sprintf("minimum cache size is %d MB", baseSize)) - } - if totalMemory != 0 && targetCache > maxCache { - log.Warn(fmt.Sprintf("Requested cache size exceeds 60%% of available memory. Reducing cache size to %d MB.", maxCache)) - targetCache = maxCache - } - - return cachescale.Ratio{ - Base: uint64(baseSize - ConstantCacheSize), - Target: uint64(targetCache - ConstantCacheSize), - } -} - -func mayMakeAllConfigs(ctx *cli.Context) (*config, error) { - // Defaults (low priority) - cacheRatio := cacheScaler(ctx) - cfg := config{ - Node: defaultNodeConfig(), - Opera: gossip.DefaultConfig(cacheRatio), - Emitter: emitter.DefaultConfig(), - TxPool: evmcore.DefaultTxPoolConfig, - OperaStore: gossip.DefaultStoreConfig(cacheRatio), - Lachesis: abft.DefaultConfig(), - LachesisStore: abft.DefaultStoreConfig(cacheRatio), - VectorClock: vecmt.DefaultConfig(cacheRatio), - } - - if ctx.GlobalIsSet(FakeNetFlag.Name) { - _, num, err := parseFakeGen(ctx.GlobalString(FakeNetFlag.Name)) - if err != nil { - return nil, fmt.Errorf("invalid fakenet flag") - } - cfg.Emitter = emitter.FakeConfig(num) - setBootnodes(ctx, []string{}, &cfg.Node) - } else { - // "asDefault" means set network defaults - cfg.Node.P2P.BootstrapNodes = asDefault - cfg.Node.P2P.BootstrapNodesV5 = asDefault - cfg.Node.P2P.TrustedNodes = asDefault - } - - // Load config file (medium priority) - if file := ctx.GlobalString(configFileFlag.Name); file != "" { - if err := loadAllConfigs(file, &cfg); err != nil { - return &cfg, err - } - } - - // Apply flags (high priority) - var err error - cfg.Opera, err = gossipConfigWithFlags(ctx, cfg.Opera) - if err != nil { - return nil, err - } - cfg.OperaStore, err = gossipStoreConfigWithFlags(ctx, cfg.OperaStore) - if err != nil { - return nil, err - } - cfg.Node = nodeConfigWithFlags(ctx, cfg.Node) - cfg.DBs = setDBConfig(ctx, cfg.DBs, cacheRatio) - - err = setValidator(ctx, &cfg.Emitter) - if err != nil { - return nil, err - } - if cfg.Emitter.Validator.ID != 0 && len(cfg.Emitter.PrevEmittedEventFile.Path) == 0 { - cfg.Emitter.PrevEmittedEventFile.Path = cfg.Node.ResolvePath(path.Join("emitter", fmt.Sprintf("last-%d", cfg.Emitter.Validator.ID))) - } - setTxPool(ctx, &cfg.TxPool) - - // Process DBs defaults in the end because they are applied only in absence of config or flags - cfg = setDBConfigDefault(cfg, cacheRatio) - // Sanitize GPO config - if cfg.Opera.GPO.MinGasTip == nil || cfg.Opera.GPO.MinGasTip.Sign() == 0 { - cfg.Opera.GPO.MinGasTip = new(big.Int).SetUint64(cfg.TxPool.PriceLimit) - } - if cfg.Opera.GPO.MinGasTip.Cmp(new(big.Int).SetUint64(cfg.TxPool.PriceLimit)) < 0 { - log.Warn(fmt.Sprintf("GPO minimum gas tip (Opera.GPO.MinGasTip=%s) is lower than txpool minimum gas tip (TxPool.PriceLimit=%d)", cfg.Opera.GPO.MinGasTip.String(), cfg.TxPool.PriceLimit)) - } - - if err := cfg.Opera.Validate(); err != nil { - return nil, err - } - - return &cfg, nil -} - -func makeAllConfigs(ctx *cli.Context) *config { - cfg, err := mayMakeAllConfigs(ctx) - if err != nil { - utils.Fatalf("%v", err) - } - return cfg -} - -func defaultNodeConfig() node.Config { - cfg := NodeDefaultConfig - cfg.Name = clientIdentifier - cfg.Version = params.VersionWithCommit(gitCommit, gitDate) - cfg.HTTPModules = append(cfg.HTTPModules, "eth", "ftm", "dag", "abft", "web3") - cfg.WSModules = append(cfg.WSModules, "eth", "ftm", "dag", "abft", "web3") - cfg.IPCPath = "x1.ipc" - cfg.DataDir = DefaultDataDir() - return cfg -} - -// dumpConfig is the dumpconfig command. -func dumpConfig(ctx *cli.Context) error { - cfg := makeAllConfigs(ctx) - comment := "" - - out, err := tomlSettings.Marshal(&cfg) - if err != nil { - return err - } - - dump := os.Stdout - if ctx.NArg() > 0 { - dump, err = os.OpenFile(ctx.Args().Get(0), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return err - } - defer dump.Close() - } - dump.WriteString(comment) - dump.Write(out) - - return nil -} - -func checkConfig(ctx *cli.Context) error { - _, err := mayMakeAllConfigs(ctx) - return err -} diff --git a/evm/go-x1/cmd/opera/launcher/config_custom.go b/evm/go-x1/cmd/opera/launcher/config_custom.go deleted file mode 100644 index b842e5b..0000000 --- a/evm/go-x1/cmd/opera/launcher/config_custom.go +++ /dev/null @@ -1,79 +0,0 @@ -package launcher - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/naoina/toml" - "github.com/naoina/toml/ast" -) - -// asDefault is slice with one empty element -// which indicates that network default bootnodes should be substituted -var asDefault = []*enode.Node{{}} - -func needDefaultBootnodes(nn []*enode.Node) bool { - return len(nn) == len(asDefault) && nn[0] == asDefault[0] -} - -func isBootstrapNodesDefault(root *ast.Table) ( - bootstrapNodes bool, - bootstrapNodesV5 bool, -) { - table := root - for _, path := range []string{"Node", "P2P"} { - val, ok := table.Fields[path] - if !ok { - return - } - table = val.(*ast.Table) - } - - emptyNode := fmt.Sprintf("\"%s\"", asDefault[0]) - - var res = map[string]bool{ - "BootstrapNodes": false, - "BootstrapNodesV5": false, - } - for name := range res { - if val, ok := table.Fields[name]; ok { - kv := val.(*ast.KeyValue) - arr := kv.Value.(*ast.Array) - if len(arr.Value) == len(asDefault) && arr.Value[0].Source() == emptyNode { - res[name] = true - delete(table.Fields, name) - } - } - } - bootstrapNodes = res["BootstrapNodes"] - bootstrapNodesV5 = res["BootstrapNodesV5"] - - return -} - -// UnmarshalTOML implements toml.Unmarshaler. -func (c *config) UnmarshalTOML(input []byte) error { - ast, err := toml.Parse(input) - if err != nil { - return err - } - - defaultBootstrapNodes, defaultBootstrapNodesV5 := isBootstrapNodesDefault(ast) - - type rawCfg config - var raw = rawCfg(*c) - err = toml.UnmarshalTable(ast, &raw) - if err != nil { - return err - } - *c = config(raw) - - if defaultBootstrapNodes { - c.Node.P2P.BootstrapNodes = asDefault - } - if defaultBootstrapNodesV5 { - c.Node.P2P.BootstrapNodesV5 = asDefault - } - - return nil -} diff --git a/evm/go-x1/cmd/opera/launcher/config_custom_test.go b/evm/go-x1/cmd/opera/launcher/config_custom_test.go deleted file mode 100644 index 2db8bfc..0000000 --- a/evm/go-x1/cmd/opera/launcher/config_custom_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package launcher - -import ( - "bytes" - "testing" - - "github.com/Fantom-foundation/lachesis-base/abft" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/vecmt" -) - -func TestConfigFile(t *testing.T) { - cacheRatio := cachescale.Ratio{ - Base: uint64(DefaultCacheSize*1 - ConstantCacheSize), - Target: uint64(DefaultCacheSize*2 - ConstantCacheSize), - } - - src := config{ - Node: defaultNodeConfig(), - Opera: gossip.DefaultConfig(cacheRatio), - Emitter: emitter.DefaultConfig(), - TxPool: evmcore.DefaultTxPoolConfig, - OperaStore: gossip.DefaultStoreConfig(cacheRatio), - Lachesis: abft.DefaultConfig(), - LachesisStore: abft.DefaultStoreConfig(cacheRatio), - VectorClock: vecmt.DefaultConfig(cacheRatio), - } - - canonical := func(nn []*enode.Node) []*enode.Node { - if len(nn) == 0 { - return []*enode.Node{} - } - return nn - } - - for name, val := range map[string][]*enode.Node{ - "Nil": nil, - "Empty": {}, - "Default": asDefault, - "UserDefined": {enode.MustParse( - "enr:-HW4QIEFxJwyZzPQJPE2DbQpEu7FM1Gv99VqJ3CbLb22fm9_V9cfdZdSBpZCyrEb5UfMeC6k9WT0iaaeAjRcuzCfr4yAgmlkgnY0iXNlY3AyNTZrMaECps0D9hhmXEN5BMgVVe0xT5mpYU9zv4YxCdTApmfP-l0", - )}, - } { - t.Run(name+"BootstrapNodes", func(t *testing.T) { - require := require.New(t) - - src.Node.P2P.BootstrapNodes = val - src.Node.P2P.BootstrapNodesV5 = val - - stream, err := tomlSettings.Marshal(&src) - require.NoError(err) - - var got config - err = tomlSettings.NewDecoder(bytes.NewReader(stream)).Decode(&got) - require.NoError(err) - - { // toml workaround - src.Node.P2P.BootstrapNodes = canonical(src.Node.P2P.BootstrapNodes) - got.Node.P2P.BootstrapNodes = canonical(got.Node.P2P.BootstrapNodes) - src.Node.P2P.BootstrapNodesV5 = canonical(src.Node.P2P.BootstrapNodesV5) - got.Node.P2P.BootstrapNodesV5 = canonical(got.Node.P2P.BootstrapNodesV5) - } - - require.Equal(src.Node.P2P.BootstrapNodes, got.Node.P2P.BootstrapNodes) - require.Equal(src.Node.P2P.BootstrapNodesV5, got.Node.P2P.BootstrapNodesV5) - }) - } -} diff --git a/evm/go-x1/cmd/opera/launcher/consolecmd.go b/evm/go-x1/cmd/opera/launcher/consolecmd.go deleted file mode 100644 index eda33bf..0000000 --- a/evm/go-x1/cmd/opera/launcher/consolecmd.go +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package launcher - -import ( - "fmt" - "os" - "os/signal" - "strings" - "syscall" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/console" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/rpc" - "gopkg.in/urfave/cli.v1" -) - -var ( - consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} - - consoleCommand = cli.Command{ - Action: utils.MigrateFlags(localConsole), - Name: "console", - Usage: "Start an interactive JavaScript environment", - Flags: append(append(append(nodeFlags, rpcFlags...), consoleFlags...), testFlags...), - Category: "CONSOLE COMMANDS", - Description: ` -The opera console is an interactive shell for the JavaScript runtime environment -which exposes a node admin interface as well as the Ðapp JavaScript API. -See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console.`, - } - - attachCommand = cli.Command{ - Action: utils.MigrateFlags(remoteConsole), - Name: "attach", - Usage: "Start an interactive JavaScript environment (connect to node)", - ArgsUsage: "[endpoint]", - Flags: append(consoleFlags, DataDirFlag), - Category: "CONSOLE COMMANDS", - Description: ` -The opera console is an interactive shell for the JavaScript runtime environment -which exposes a node admin interface as well as the Ðapp JavaScript API. -See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console. -This command allows to open a console on a running opera node.`, - } - - javascriptCommand = cli.Command{ - Action: utils.MigrateFlags(ephemeralConsole), - Name: "js", - Usage: "Execute the specified JavaScript files", - ArgsUsage: " [jsfile...]", - Flags: append(append(nodeFlags, consoleFlags...), testFlags...), - Category: "CONSOLE COMMANDS", - Description: ` -The JavaScript VM exposes a node admin interface as well as the Ðapp -JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console`, - } -) - -// localConsole starts a new opera node, attaching a JavaScript console to it at the -// same time. -func localConsole(ctx *cli.Context) error { - // Create and start the node based on the CLI flags - cfg := makeAllConfigs(ctx) - genesisStore := mayGetGenesisStore(ctx) - node, _, nodeClose := makeNode(ctx, cfg, genesisStore) - startNode(ctx, node) - defer nodeClose() - - // Attach to the newly started node and start the JavaScript console - client, err := node.Attach() - if err != nil { - utils.Fatalf("Failed to attach to the inproc opera: %v", err) - } - config := console.Config{ - DataDir: utils.MakeDataDir(ctx), - DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), - Client: client, - Preload: utils.MakeConsolePreloads(ctx), - } - - console, err := console.New(config) - if err != nil { - utils.Fatalf("Failed to start the JavaScript console: %v", err) - } - defer console.Stop(false) - - // If only a short execution was requested, evaluate and return - if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { - console.Evaluate(script) - return nil - } - // Otherwise print the welcome screen and enter interactive mode - console.Welcome() - console.Interactive() - - return nil -} - -// remoteConsole will connect to a remote opera instance, attaching a JavaScript -// console to it. -func remoteConsole(ctx *cli.Context) error { - // Attach to a remotely running opera instance and start the JavaScript console - endpoint := ctx.Args().First() - if endpoint == "" { - path := DefaultDataDir() - if ctx.GlobalIsSet(DataDirFlag.Name) { - path = ctx.GlobalString(DataDirFlag.Name) - } - endpoint = fmt.Sprintf("%s/x1.ipc", path) - } - client, err := dialRPC(endpoint) - if err != nil { - utils.Fatalf("Unable to attach to remote opera: %v", err) - } - config := console.Config{ - DataDir: utils.MakeDataDir(ctx), - DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), - Client: client, - Preload: utils.MakeConsolePreloads(ctx), - } - - console, err := console.New(config) - if err != nil { - utils.Fatalf("Failed to start the JavaScript console: %v", err) - } - defer console.Stop(false) - - if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { - console.Evaluate(script) - return nil - } - - // Otherwise print the welcome screen and enter interactive mode - console.Welcome() - console.Interactive() - - return nil -} - -// dialRPC returns a RPC client which connects to the given endpoint. -// The check for empty endpoint implements the defaulting logic -// for "opera attach" and "opera monitor" with no argument. -func dialRPC(endpoint string) (*rpc.Client, error) { - if endpoint == "" { - endpoint = node.DefaultIPCEndpoint(clientIdentifier) - } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { - // Backwards compatibility with rpc which required these prefixes. - endpoint = endpoint[4:] - } - return rpc.Dial(endpoint) -} - -// ephemeralConsole starts a new opera node, attaches an ephemeral JavaScript -// console to it, executes each of the files specified as arguments and tears -// everything down. -func ephemeralConsole(ctx *cli.Context) error { - // Create and start the node based on the CLI flags - cfg := makeAllConfigs(ctx) - genesisStore := mayGetGenesisStore(ctx) - node, _, nodeClose := makeNode(ctx, cfg, genesisStore) - startNode(ctx, node) - defer nodeClose() - - // Attach to the newly started node and start the JavaScript console - client, err := node.Attach() - if err != nil { - utils.Fatalf("Failed to attach to the inproc opera: %v", err) - } - config := console.Config{ - DataDir: utils.MakeDataDir(ctx), - DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), - Client: client, - Preload: utils.MakeConsolePreloads(ctx), - } - - console, err := console.New(config) - if err != nil { - utils.Fatalf("Failed to start the JavaScript console: %v", err) - } - defer console.Stop(false) - - // Evaluate each of the specified JavaScript files - for _, file := range ctx.Args() { - if err = console.Execute(file); err != nil { - utils.Fatalf("Failed to execute %s: %v", file, err) - } - } - // Wait for pending callbacks, but stop for Ctrl-C. - abort := make(chan os.Signal, 1) - signal.Notify(abort, syscall.SIGINT, syscall.SIGTERM) - - go func() { - <-abort - os.Exit(0) - }() - console.Stop(true) - - return nil -} diff --git a/evm/go-x1/cmd/opera/launcher/consolecmd_test.go b/evm/go-x1/cmd/opera/launcher/consolecmd_test.go deleted file mode 100644 index 5e708d6..0000000 --- a/evm/go-x1/cmd/opera/launcher/consolecmd_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package launcher - -import ( - "crypto/rand" - "math/big" - "os" - "path/filepath" - "runtime" - "strconv" - "strings" - "testing" - "time" - - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" -) - -const ( - ipcAPIs = "abft:1.0 admin:1.0 dag:1.0 debug:1.0 ftm:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0" - httpAPIs = "abft:1.0 dag:1.0 ftm:1.0 rpc:1.0 web3:1.0" -) - -// Tests that a node embedded within a console can be started up properly and -// then terminated by closing the input stream. -func TestConsoleWelcome(t *testing.T) { - // Start an opera console, make sure it's cleaned up and terminate the console - cli := exec(t, - "--fakenet", "0/1", "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "console") - - // Gather all the infos the welcome message needs to contain - cli.SetTemplateFunc("goos", func() string { return runtime.GOOS }) - cli.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) - cli.SetTemplateFunc("gover", runtime.Version) - cli.SetTemplateFunc("version", func() string { return params.VersionWithCommit("", "") }) - cli.SetTemplateFunc("niltime", genesisStart) - cli.SetTemplateFunc("apis", func() string { return ipcAPIs }) - - // Verify the actual welcome message to the required template - cli.Expect(` -Welcome to the Lachesis JavaScript console! - -instance: go-opera/v{{version}}/{{goos}}-{{goarch}}/{{gover}} -coinbase: {{.Coinbase}} -at block: 1 ({{niltime}}) - datadir: {{.Datadir}} - modules: {{apis}} - -To exit, press ctrl-d -> {{.InputLine "exit"}} -`) - cli.ExpectExit() -} - -// Tests that a console can be attached to a running node via various means. -func TestIPCAttachWelcome(t *testing.T) { - // Configure the instance for IPC attachement - var ipc string - if runtime.GOOS == "windows" { - ipc = `\\.\pipe\lachesis.ipc` - } else { - ws := tmpdir(t) - defer os.RemoveAll(ws) - ipc = filepath.Join(ws, "x1.ipc") - } - cli := exec(t, - "--fakenet", "0/1", "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "--ipcpath", ipc) - - waitForEndpoint(t, ipc, 60*time.Second) - testAttachWelcome(t, cli, "ipc:"+ipc, ipcAPIs) - - cli.Kill() - cli.WaitExit() -} - -func TestHTTPAttachWelcome(t *testing.T) { - port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P - cli := exec(t, - "--fakenet", "0/1", "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "--http", "--http.port", port) - - endpoint := "http://127.0.0.1:" + port - waitForEndpoint(t, endpoint, 60*time.Second) - testAttachWelcome(t, cli, "http://localhost:"+port, httpAPIs) - - cli.Kill() - cli.WaitExit() -} - -func TestWSAttachWelcome(t *testing.T) { - port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P - - cli := exec(t, - "--fakenet", "0/1", "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "--ws", "--ws.port", port) - - endpoint := "ws://127.0.0.1:" + port - waitForEndpoint(t, endpoint, 60*time.Second) - testAttachWelcome(t, cli, "ws://localhost:"+port, httpAPIs) - - cli.Kill() - cli.WaitExit() -} - -func testAttachWelcome(t *testing.T, cli *testcli, endpoint, apis string) { - // Attach to a running opera node and terminate immediately - attach := exec(t, "attach", endpoint) - - // Gather all the infos the welcome message needs to contain - attach.SetTemplateFunc("goos", func() string { return runtime.GOOS }) - attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) - attach.SetTemplateFunc("gover", runtime.Version) - attach.SetTemplateFunc("version", func() string { return params.VersionWithCommit("", "") }) - attach.SetTemplateFunc("niltime", genesisStart) - attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") }) - attach.SetTemplateFunc("datadir", func() string { return cli.Datadir }) - attach.SetTemplateFunc("coinbase", func() string { return cli.Coinbase }) - attach.SetTemplateFunc("apis", func() string { return apis }) - - // Verify the actual welcome message to the required template - attach.Expect(` -Welcome to the Lachesis JavaScript console! - -instance: go-opera/v{{version}}/{{goos}}-{{goarch}}/{{gover}} -coinbase: {{coinbase}} -at block: 1 ({{niltime}}){{if ipc}} - datadir: {{datadir}}{{end}} - modules: {{apis}} - -To exit, press ctrl-d -> {{.InputLine "exit" }} -`) - attach.ExpectExit() -} - -// trulyRandInt generates a crypto random integer used by the console tests to -// not clash network ports with other tests running cocurrently. -func trulyRandInt(lo, hi int) int { - num, _ := rand.Int(rand.Reader, big.NewInt(int64(hi-lo))) - return int(num.Int64()) + lo -} - -func genesisStart() string { - return time.Unix(int64(makefakegenesis.FakeGenesisTime.Unix()), 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)") -} diff --git a/evm/go-x1/cmd/opera/launcher/db-transform.go b/evm/go-x1/cmd/opera/launcher/db-transform.go deleted file mode 100644 index 046c025..0000000 --- a/evm/go-x1/cmd/opera/launcher/db-transform.go +++ /dev/null @@ -1,349 +0,0 @@ -package launcher - -import ( - "os" - "path" - "strings" - "time" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/batched" - "github.com/Fantom-foundation/lachesis-base/kvdb/multidb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/syndtr/goleveldb/leveldb/opt" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/integration" - "github.com/Fantom-foundation/go-opera/utils" - "github.com/Fantom-foundation/go-opera/utils/dbutil/autocompact" -) - -func dbTransform(ctx *cli.Context) error { - cfg := makeAllConfigs(ctx) - - tmpPath := path.Join(cfg.Node.DataDir, "tmp") - integration.MakeDBDirs(tmpPath) - _ = os.RemoveAll(tmpPath) - defer os.RemoveAll(tmpPath) - - // get supported DB producers - dbTypes := makeUncheckedCachedDBsProducers(path.Join(cfg.Node.DataDir, "chaindata")) - - byReq, err := readRoutes(cfg, dbTypes) - if err != nil { - log.Crit("Failed to read routes", "err", err) - } - byDB := separateIntoDBs(byReq) - - // weed out DBs which don't need transformation - { - for _, byReqOfDB := range byDB { - match := true - for _, e := range byReqOfDB { - if e.Old != e.New { - match = false - break - } - } - if match { - for _, e := range byReqOfDB { - delete(byReq, e.Req) - } - } - } - } - if len(byReq) == 0 { - log.Info("No DB transformation is needed") - return nil - } - - // check if new layout is contradictory - for _, e0 := range byReq { - for _, e1 := range byReq { - if e0 == e1 { - continue - } - if dbLocatorOf(e0.New) == dbLocatorOf(e1.New) && strings.HasPrefix(e0.New.Table, e1.New.Table) { - log.Crit("New DB layout is contradictory", "db_type", e0.New.Type, "db_name", e0.New.Name, - "req0", e0.Req, "req1", e1.Req, "table0", e0.New.Table, "table1", e1.New.Table) - } - } - } - - // separate entries into inter-linked components - byComponents := make([]map[string]dbMigrationEntry, 0) - for componentI := 0; len(byReq) > 0; componentI++ { - var someEntry dbMigrationEntry - for _, e := range byReq { - someEntry = e - break - } - - // DFS - component := make(map[string]dbMigrationEntry) - stack := make(dbMigrationEntries, 0) - for pwalk := &someEntry; pwalk != nil; pwalk = stack.Pop() { - if _, ok := component[pwalk.Req]; ok { - continue - } - component[pwalk.Req] = *pwalk - delete(byReq, pwalk.Req) - for _, e := range byDB[dbLocatorOf(pwalk.Old)] { - stack = append(stack, e) - } - for _, e := range byDB[dbLocatorOf(pwalk.New)] { - stack = append(stack, e) - } - } - byComponents = append(byComponents, component) - } - - tmpDbTypes := makeUncheckedCachedDBsProducers(path.Join(cfg.Node.DataDir, "tmp")) - for _, component := range byComponents { - err := transformComponent(cfg.Node.DataDir, dbTypes, tmpDbTypes, component) - if err != nil { - log.Crit("Failed to transform component", "err", err) - } - } - id := bigendian.Uint64ToBytes(uint64(time.Now().UnixNano())) - for typ, producer := range dbTypes { - err := clearDirtyFlags(id, producer) - if err != nil { - log.Crit("Failed to write clean FlushID", "type", typ, "err", err) - } - } - - memorizeDBPreset(cfg) - log.Info("DB transformation is complete") - - return nil -} - -type dbMigrationEntry struct { - Req string - Old multidb.Route - New multidb.Route -} - -type dbMigrationEntries []dbMigrationEntry - -func (ee *dbMigrationEntries) Pop() *dbMigrationEntry { - l := len(*ee) - if l == 0 { - return nil - } - res := &(*ee)[l-1] - *ee = (*ee)[:l-1] - return res -} - -var dbLocatorOf = multidb.DBLocatorOf - -func readRoutes(cfg *config, dbTypes map[multidb.TypeName]kvdb.FullDBProducer) (map[string]dbMigrationEntry, error) { - router, err := multidb.NewProducer(dbTypes, cfg.DBs.Routing.Table, integration.TablesKey) - if err != nil { - return nil, err - } - byReq := make(map[string]dbMigrationEntry) - - for typ, producer := range dbTypes { - for _, dbName := range producer.Names() { - db, err := producer.OpenDB(dbName) - if err != nil { - log.Crit("DB opening error", "name", dbName, "err", err) - } - defer db.Close() - tables, err := multidb.ReadTablesList(db, integration.TablesKey) - if err != nil { - log.Crit("Failed to read tables list", "name", dbName, "err", err) - } - for _, t := range tables { - oldRoute := multidb.Route{ - Type: typ, - Name: dbName, - Table: t.Table, - } - newRoute := router.RouteOf(t.Req) - newRoute.NoDrop = false - byReq[t.Req] = dbMigrationEntry{ - Req: t.Req, - New: newRoute, - Old: oldRoute, - } - } - } - } - return byReq, nil -} - -func writeCleanTableRecords(dbTypes map[multidb.TypeName]kvdb.FullDBProducer, byReq map[string]dbMigrationEntry) error { - records := make(map[multidb.DBLocator][]multidb.TableRecord, 0) - for _, e := range byReq { - records[dbLocatorOf(e.New)] = append(records[dbLocatorOf(e.New)], multidb.TableRecord{ - Req: e.Req, - Table: e.New.Table, - }) - } - written := make(map[multidb.DBLocator]bool) - for _, e := range byReq { - if written[dbLocatorOf(e.New)] { - continue - } - written[dbLocatorOf(e.New)] = true - - db, err := dbTypes[e.New.Type].OpenDB(e.New.Name) - if err != nil { - return err - } - defer db.Close() - err = multidb.WriteTablesList(db, integration.TablesKey, records[dbLocatorOf(e.New)]) - if err != nil { - return err - } - } - return nil -} - -func interchangeableType(a_, b_ multidb.TypeName, types map[multidb.TypeName]kvdb.FullDBProducer) bool { - for t_ := range types { - a, b, t := string(a_), string(b_), string(t_) - t = strings.TrimSuffix(t, "fsh") - t = strings.TrimSuffix(t, "flg") - t = strings.TrimSuffix(t, "drc") - if strings.HasPrefix(a, t) && strings.HasPrefix(b, t) { - return true - } - } - return false -} - -func transformComponent(datadir string, dbTypes, tmpDbTypes map[multidb.TypeName]kvdb.FullDBProducer, byReq map[string]dbMigrationEntry) error { - byDB := separateIntoDBs(byReq) - // if it can be transformed just by DB renaming - if len(byDB) == 2 { - oldDB := multidb.DBLocator{} - newDB := multidb.DBLocator{} - ok := true - for _, e := range byReq { - if len(oldDB.Type) == 0 { - oldDB = dbLocatorOf(e.Old) - newDB = dbLocatorOf(e.New) - } - if !interchangeableType(oldDB.Type, newDB.Type, dbTypes) || e.Old.Table != e.New.Table || e.New.Name != newDB.Name || - e.Old.Name != oldDB.Name || e.Old.Type != oldDB.Type || e.New.Type != newDB.Type { - ok = false - break - } - } - if ok { - oldPath := path.Join(datadir, "chaindata", string(oldDB.Type), oldDB.Name) - newPath := path.Join(datadir, "chaindata", string(newDB.Type), newDB.Name) - log.Info("Renaming DB", "old", oldPath, "new", newPath) - return os.Rename(oldPath, newPath) - } - } - - toMove := make(map[multidb.DBLocator]bool) - { - const batchKeys = 100000 - keys := make([][]byte, 0, batchKeys) - values := make([][]byte, 0, batchKeys) - for _, e := range byReq { - err := func() error { - oldDB, err := dbTypes[e.Old.Type].OpenDB(e.Old.Name) - if err != nil { - return err - } - oldDB = batched.Wrap(oldDB) - defer oldDB.Close() - oldHumanName := path.Join(string(e.Old.Type), e.Old.Name) - newDB, err := tmpDbTypes[e.New.Type].OpenDB(e.New.Name) - if err != nil { - return err - } - toMove[dbLocatorOf(e.New)] = true - newHumanName := path.Join("tmp", string(e.New.Type), e.New.Name) - newDB = batched.Wrap(autocompact.Wrap2M(newDB, opt.GiB, 16*opt.GiB, true, newHumanName)) - defer newDB.Close() - log.Info("Copying DB table", "req", e.Req, "old_db", oldHumanName, "old_table", e.Old.Table, - "new_db", newHumanName, "new_table", e.New.Table) - oldTable := utils.NewTableOrSelf(oldDB, []byte(e.Old.Table)) - newTable := utils.NewTableOrSelf(newDB, []byte(e.New.Table)) - it := oldTable.NewIterator(nil, nil) - defer it.Release() - - for next := true; next; { - for len(keys) < batchKeys { - next = it.Next() - if !next { - break - } - keys = append(keys, common.CopyBytes(it.Key())) - values = append(values, common.CopyBytes(it.Value())) - } - for i := 0; i < len(keys); i++ { - err = newTable.Put(keys[i], values[i]) - if err != nil { - return err - } - } - keys = keys[:0] - values = values[:0] - } - return nil - }() - if err != nil { - return err - } - } - } - - // finalize tmp DBs - err := writeCleanTableRecords(tmpDbTypes, byReq) - if err != nil { - return err - } - - // drop unused DBs - dropped := make(map[multidb.DBLocator]bool) - for _, e := range byReq { - if dropped[dbLocatorOf(e.Old)] { - continue - } - dropped[dbLocatorOf(e.Old)] = true - log.Info("Dropping old DB", "db_type", e.Old.Type, "db_name", e.Old.Name) - deletePath := path.Join(datadir, "chaindata", string(e.Old.Type), e.Old.Name) - err := os.RemoveAll(deletePath) - if err != nil { - return err - } - } - // move tmp DBs - for e := range toMove { - oldPath := path.Join(datadir, "tmp", string(e.Type), e.Name) - newPath := path.Join(datadir, "chaindata", string(e.Type), e.Name) - log.Info("Moving tmp DB to clean dir", "old", oldPath, "new", newPath) - err := os.Rename(oldPath, newPath) - if err != nil { - return err - } - } - return nil -} - -func separateIntoDBs(byReq map[string]dbMigrationEntry) map[multidb.DBLocator]map[string]dbMigrationEntry { - byDB := make(map[multidb.DBLocator]map[string]dbMigrationEntry) - for _, e := range byReq { - if byDB[dbLocatorOf(e.Old)] == nil { - byDB[dbLocatorOf(e.Old)] = make(map[string]dbMigrationEntry) - } - byDB[dbLocatorOf(e.Old)][e.Req] = e - if byDB[dbLocatorOf(e.New)] == nil { - byDB[dbLocatorOf(e.New)] = make(map[string]dbMigrationEntry) - } - byDB[dbLocatorOf(e.New)][e.Req] = e - } - return byDB -} diff --git a/evm/go-x1/cmd/opera/launcher/dbcmd.go b/evm/go-x1/cmd/opera/launcher/dbcmd.go deleted file mode 100644 index 4c24da4..0000000 --- a/evm/go-x1/cmd/opera/launcher/dbcmd.go +++ /dev/null @@ -1,175 +0,0 @@ -package launcher - -import ( - "fmt" - "path" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/cachedproducer" - "github.com/Fantom-foundation/lachesis-base/kvdb/multidb" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/syndtr/goleveldb/leveldb/opt" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/integration" - "github.com/Fantom-foundation/go-opera/utils/dbutil/compactdb" -) - -var ( - experimentalFlag = cli.BoolFlag{ - Name: "experimental", - Usage: "Allow experimental DB fixing", - } - dbCommand = cli.Command{ - Name: "db", - Usage: "A set of commands related to leveldb database", - Category: "DB COMMANDS", - Description: "", - Subcommands: []cli.Command{ - { - Name: "compact", - Usage: "Compact all databases", - ArgsUsage: "", - Action: utils.MigrateFlags(compact), - Category: "DB COMMANDS", - Flags: []cli.Flag{ - utils.DataDirFlag, - }, - Description: ` -opera db compact -will compact all databases under datadir's chaindata. -`, - }, - { - Name: "transform", - Usage: "Transform DBs layout", - ArgsUsage: "", - Action: utils.MigrateFlags(dbTransform), - Category: "DB COMMANDS", - Flags: []cli.Flag{ - utils.DataDirFlag, - }, - Description: ` -opera db transform -will migrate tables layout according to the configuration. -`, - }, - { - Name: "heal", - Usage: "Experimental - try to heal dirty DB", - ArgsUsage: "", - Action: utils.MigrateFlags(healDirty), - Category: "DB COMMANDS", - Flags: []cli.Flag{ - utils.DataDirFlag, - experimentalFlag, - }, - Description: ` -opera db heal --experimental -Experimental - try to heal dirty DB. -`, - }, - }, - } -) - -func makeUncheckedDBsProducers(cfg *config) map[multidb.TypeName]kvdb.IterableDBProducer { - dbsList, _ := integration.SupportedDBs(path.Join(cfg.Node.DataDir, "chaindata"), cfg.DBs.RuntimeCache) - return dbsList -} - -func makeUncheckedCachedDBsProducers(chaindataDir string) map[multidb.TypeName]kvdb.FullDBProducer { - dbTypes, _ := integration.SupportedDBs(chaindataDir, integration.DBsCacheConfig{ - Table: map[string]integration.DBCacheConfig{ - "": { - Cache: 1024 * opt.MiB, - Fdlimit: uint64(utils.MakeDatabaseHandles() / 2), - }, - }, - }) - wrappedDbTypes := make(map[multidb.TypeName]kvdb.FullDBProducer) - for typ, producer := range dbTypes { - wrappedDbTypes[typ] = cachedproducer.WrapAll(&integration.DummyScopedProducer{IterableDBProducer: producer}) - } - return wrappedDbTypes -} - -func makeCheckedDBsProducers(cfg *config) map[multidb.TypeName]kvdb.IterableDBProducer { - if err := integration.CheckStateInitialized(path.Join(cfg.Node.DataDir, "chaindata"), cfg.DBs); err != nil { - utils.Fatalf(err.Error()) - } - return makeUncheckedDBsProducers(cfg) -} - -func makeDirectDBsProducerFrom(dbsList map[multidb.TypeName]kvdb.IterableDBProducer, cfg *config) kvdb.FullDBProducer { - multiRawDbs, err := integration.MakeDirectMultiProducer(dbsList, cfg.DBs.Routing) - if err != nil { - utils.Fatalf("Failed to initialize multi DB producer: %v", err) - } - return multiRawDbs -} - -func makeDirectDBsProducer(cfg *config) kvdb.FullDBProducer { - dbsList := makeCheckedDBsProducers(cfg) - return makeDirectDBsProducerFrom(dbsList, cfg) -} - -func makeGossipStore(producer kvdb.FlushableDBProducer, cfg *config) *gossip.Store { - return gossip.NewStore(producer, cfg.OperaStore) -} - -func compact(ctx *cli.Context) error { - - cfg := makeAllConfigs(ctx) - - producers := makeCheckedDBsProducers(cfg) - for typ, p := range producers { - for _, name := range p.Names() { - if err := compactDB(typ, name, p); err != nil { - return err - } - } - } - - return nil -} - -func compactDB(typ multidb.TypeName, name string, producer kvdb.DBProducer) error { - humanName := path.Join(string(typ), name) - db, err := producer.OpenDB(name) - defer db.Close() - if err != nil { - log.Error("Cannot open db or db does not exists", "db", humanName) - return err - } - - log.Info("Stats before compaction", "db", humanName) - showDbStats(db) - - err = compactdb.Compact(db, humanName, 64*opt.GiB) - if err != nil { - log.Error("Database compaction failed", "err", err) - return err - } - - log.Info("Stats after compaction", "db", humanName) - showDbStats(db) - - return nil -} - -func showDbStats(db ethdb.Stater) { - if stats, err := db.Stat("stats"); err != nil { - log.Warn("Failed to read database stats", "error", err) - } else { - fmt.Println(stats) - } - if ioStats, err := db.Stat("iostats"); err != nil { - log.Warn("Failed to read database iostats", "error", err) - } else { - fmt.Println(ioStats) - } -} diff --git a/evm/go-x1/cmd/opera/launcher/defaults.go b/evm/go-x1/cmd/opera/launcher/defaults.go deleted file mode 100644 index 3cc016d..0000000 --- a/evm/go-x1/cmd/opera/launcher/defaults.go +++ /dev/null @@ -1,105 +0,0 @@ -package launcher - -import ( - "fmt" - "os" - "os/user" - "path/filepath" - "runtime" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/nat" - "github.com/ethereum/go-ethereum/rpc" -) - -const ( - DefaultP2PPort = 5050 // Default p2p port for listening - DefaultHTTPPort = 18545 // Default TCP port for the HTTP RPC server - DefaultWSPort = 18546 // Default TCP port for the websocket RPC server -) - -func overrideFlags() { - utils.ListenPortFlag.Value = DefaultP2PPort - utils.HTTPPortFlag.Value = DefaultHTTPPort - utils.LegacyRPCPortFlag.Value = DefaultHTTPPort - utils.WSPortFlag.Value = DefaultWSPort -} - -// NodeDefaultConfig contains reasonable default settings. -var NodeDefaultConfig = node.Config{ - DataDir: DefaultDataDir(), - HTTPPort: DefaultHTTPPort, - HTTPModules: []string{}, - HTTPVirtualHosts: []string{"localhost"}, - HTTPTimeouts: rpc.DefaultHTTPTimeouts, - WSPort: DefaultWSPort, - WSModules: []string{}, - GraphQLVirtualHosts: []string{"localhost"}, - P2P: p2p.Config{ - NoDiscovery: false, // enable discovery v4 by default - DiscoveryV5: true, // enable discovery v5 by default - ListenAddr: fmt.Sprintf(":%d", DefaultP2PPort), - MaxPeers: 50, - NAT: nat.Any(), - }, -} - -// DefaultDataDir is the default data directory to use for the databases and other -// persistence requirements. -func DefaultDataDir() string { - // Try to place the data folder in the user's home dir - home := homeDir() - if home != "" { - switch runtime.GOOS { - case "darwin": - return filepath.Join(home, "Library", "Lachesis") - case "windows": - // We used to put everything in %HOME%\AppData\Roaming, but this caused - // problems with non-typical setups. If this fallback location exists and - // is non-empty, use it, otherwise DTRT and check %LOCALAPPDATA%. - fallback := filepath.Join(home, "AppData", "Roaming", "Lachesis") - appdata := windowsAppData() - if appdata == "" || isNonEmptyDir(fallback) { - return fallback - } - return filepath.Join(appdata, "Lachesis") - default: - return filepath.Join(home, ".x1") - } - } - // As we cannot guess a stable location, return empty and handle later - return "" -} - -func windowsAppData() string { - v := os.Getenv("LOCALAPPDATA") - if v == "" { - // Windows XP and below don't have LocalAppData. Crash here because - // we don't support Windows XP and undefining the variable will cause - // other issues. - panic("environment variable LocalAppData is undefined") - } - return v -} - -func isNonEmptyDir(dir string) bool { - f, err := os.Open(dir) - if err != nil { - return false - } - names, _ := f.Readdir(1) - f.Close() - return len(names) > 0 -} - -func homeDir() string { - if home := os.Getenv("HOME"); home != "" { - return home - } - if usr, err := user.Current(); err == nil { - return usr.HomeDir - } - return "" -} diff --git a/evm/go-x1/cmd/opera/launcher/export.go b/evm/go-x1/cmd/opera/launcher/export.go deleted file mode 100644 index 7681f7f..0000000 --- a/evm/go-x1/cmd/opera/launcher/export.go +++ /dev/null @@ -1,155 +0,0 @@ -package launcher - -import ( - "compress/gzip" - "io" - "os" - "strconv" - "strings" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/kvdb/batched" - "github.com/Fantom-foundation/lachesis-base/kvdb/pebble" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/status-im/keycard-go/hexutils" - "github.com/syndtr/goleveldb/leveldb/opt" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/utils/dbutil/autocompact" -) - -var ( - eventsFileHeader = hexutils.HexToBytes("7e995678") - eventsFileVersion = hexutils.HexToBytes("00010001") -) - -// statsReportLimit is the time limit during import and export after which we -// always print out progress. This avoids the user wondering what's going on. -const statsReportLimit = 8 * time.Second - -func exportEvents(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { - utils.Fatalf("This command requires an argument.") - } - - cfg := makeAllConfigs(ctx) - - rawDbs := makeDirectDBsProducer(cfg) - gdb := makeGossipStore(rawDbs, cfg) - defer gdb.Close() - - fn := ctx.Args().First() - - // Open the file handle and potentially wrap with a gzip stream - fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) - if err != nil { - return err - } - defer fh.Close() - - var writer io.Writer = fh - if strings.HasSuffix(fn, ".gz") { - writer = gzip.NewWriter(writer) - defer writer.(*gzip.Writer).Close() - } - - from := idx.Epoch(1) - if len(ctx.Args()) > 1 { - n, err := strconv.ParseUint(ctx.Args().Get(1), 10, 32) - if err != nil { - return err - } - from = idx.Epoch(n) - } - to := idx.Epoch(0) - if len(ctx.Args()) > 2 { - n, err := strconv.ParseUint(ctx.Args().Get(2), 10, 32) - if err != nil { - return err - } - to = idx.Epoch(n) - } - - log.Info("Exporting events to file", "file", fn) - // Write header and version - _, err = writer.Write(append(eventsFileHeader, eventsFileVersion...)) - if err != nil { - return err - } - err = exportTo(writer, gdb, from, to) - if err != nil { - utils.Fatalf("Export error: %v\n", err) - } - - return nil -} - -// exportTo writer the active chain. -func exportTo(w io.Writer, gdb *gossip.Store, from, to idx.Epoch) (err error) { - start, reported := time.Now(), time.Time{} - - var ( - counter int - last hash.Event - ) - gdb.ForEachEventRLP(from.Bytes(), func(id hash.Event, event rlp.RawValue) bool { - if to >= from && id.Epoch() > to { - return false - } - counter++ - _, err = w.Write(event) - if err != nil { - return false - } - last = id - if counter%100 == 1 && time.Since(reported) >= statsReportLimit { - log.Info("Exporting events", "last", last.String(), "exported", counter, "elapsed", common.PrettyDuration(time.Since(start))) - reported = time.Now() - } - return true - }) - log.Info("Exported events", "last", last.String(), "exported", counter, "elapsed", common.PrettyDuration(time.Since(start))) - - return -} - -func exportEvmKeys(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { - utils.Fatalf("This command requires an argument.") - } - - cfg := makeAllConfigs(ctx) - - rawDbs := makeDirectDBsProducer(cfg) - gdb := makeGossipStore(rawDbs, cfg) - defer gdb.Close() - - fn := ctx.Args().First() - - keysDB_, err := pebble.New(fn, 1024*opt.MiB, utils.MakeDatabaseHandles()/2, nil, nil) - if err != nil { - return err - } - keysDB := batched.Wrap(autocompact.Wrap2M(keysDB_, opt.GiB, 16*opt.GiB, true, "evm-keys")) - defer keysDB.Close() - - it := gdb.EvmStore().EvmDb.NewIterator(nil, nil) - // iterate only over MPT data - it = mptAndPreimageIterator{it} - defer it.Release() - - log.Info("Exporting EVM keys", "dir", fn) - for it.Next() { - if err := keysDB.Put(it.Key(), []byte{0}); err != nil { - return err - } - } - log.Info("Exported EVM keys", "dir", fn) - return nil -} diff --git a/evm/go-x1/cmd/opera/launcher/fake.go b/evm/go-x1/cmd/opera/launcher/fake.go deleted file mode 100644 index 7c71403..0000000 --- a/evm/go-x1/cmd/opera/launcher/fake.go +++ /dev/null @@ -1,51 +0,0 @@ -package launcher - -import ( - "crypto/ecdsa" - "fmt" - "strconv" - "strings" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - cli "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" -) - -// FakeNetFlag enables special testnet, where validators are automatically created -var FakeNetFlag = cli.StringFlag{ - Name: "fakenet", - Usage: "'n/N' - sets coinbase as fake n-th key from genesis of N validators.", -} - -func getFakeValidatorKey(ctx *cli.Context) *ecdsa.PrivateKey { - id, _, err := parseFakeGen(ctx.GlobalString(FakeNetFlag.Name)) - if err != nil || id == 0 { - return nil - } - return makefakegenesis.FakeKey(id) -} - -func parseFakeGen(s string) (id idx.ValidatorID, num idx.Validator, err error) { - parts := strings.SplitN(s, "/", 2) - if len(parts) != 2 { - err = fmt.Errorf("use %%d/%%d format") - return - } - - var u32 uint64 - u32, err = strconv.ParseUint(parts[0], 10, 32) - if err != nil { - return - } - id = idx.ValidatorID(u32) - - u32, err = strconv.ParseUint(parts[1], 10, 32) - num = idx.Validator(u32) - if num < 0 || idx.Validator(id) > num { - err = fmt.Errorf("key-num should be in range from 1 to validators (/), or should be zero for non-validator node") - return - } - - return -} diff --git a/evm/go-x1/cmd/opera/launcher/fake_test.go b/evm/go-x1/cmd/opera/launcher/fake_test.go deleted file mode 100644 index c3520b8..0000000 --- a/evm/go-x1/cmd/opera/launcher/fake_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package launcher - -import ( - "path/filepath" - "runtime" - "strings" - "testing" - "time" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" - "github.com/Fantom-foundation/go-opera/inter/validatorpk" -) - -func TestFakeNetFlag_NonValidator(t *testing.T) { - // Start an opera console, make sure it's cleaned up and terminate the console - cli := exec(t, - "--fakenet", "0/3", - "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "console") - - // Gather all the infos the welcome message needs to contain - cli.SetTemplateFunc("goos", func() string { return runtime.GOOS }) - cli.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) - cli.SetTemplateFunc("gover", runtime.Version) - cli.SetTemplateFunc("version", func() string { return params.VersionWithCommit("", "") }) - cli.SetTemplateFunc("niltime", genesisStart) - cli.SetTemplateFunc("apis", func() string { return ipcAPIs }) - - waitForEndpoint(t, filepath.Join(cli.Datadir, "x1.ipc"), 60*time.Second) - - // Verify the actual welcome message to the required template - cli.Expect(` -Welcome to the Lachesis JavaScript console! - -instance: go-opera/v{{version}}/{{goos}}-{{goarch}}/{{gover}} -coinbase: {{.Coinbase}} -at block: 1 ({{niltime}}) - datadir: {{.Datadir}} - modules: {{apis}} - -To exit, press ctrl-d -> {{.InputLine "exit"}} -`) - cli.ExpectExit() - - wantMessages := []string{ - "Unlocked fake validator", - } - for _, m := range wantMessages { - if strings.Contains(cli.StderrText(), m) { - t.Errorf("stderr text contains %q", m) - } - } -} - -func TestFakeNetFlag_Validator(t *testing.T) { - // Start an opera console, make sure it's cleaned up and terminate the console - cli := exec(t, - "--fakenet", "3/3", - "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "console") - - // Gather all the infos the welcome message needs to contain - va := readFakeValidator("3/3") - cli.Coinbase = "0x0000000000000000000000000000000000000000" - cli.SetTemplateFunc("goos", func() string { return runtime.GOOS }) - cli.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) - cli.SetTemplateFunc("gover", runtime.Version) - cli.SetTemplateFunc("version", func() string { return params.VersionWithCommit("", "") }) - cli.SetTemplateFunc("niltime", genesisStart) - cli.SetTemplateFunc("apis", func() string { return ipcAPIs }) - - waitForEndpoint(t, filepath.Join(cli.Datadir, "x1.ipc"), 60*time.Second) - - // Verify the actual welcome message to the required template - cli.Expect(` -Welcome to the Lachesis JavaScript console! - -instance: go-opera/v{{version}}/{{goos}}-{{goarch}}/{{gover}} -coinbase: {{.Coinbase}} -at block: 1 ({{niltime}}) - datadir: {{.Datadir}} - modules: {{apis}} - -To exit, press ctrl-d -> {{.InputLine "exit"}} -`) - cli.ExpectExit() - - wantMessages := []string{ - "Unlocked validator key", - "pubkey=" + va.String(), - } - for _, m := range wantMessages { - if !strings.Contains(cli.StderrText(), m) { - t.Errorf("stderr text does not contain %q", m) - } - } -} - -func readFakeValidator(fakenet string) *validatorpk.PubKey { - n, _, err := parseFakeGen(fakenet) - if err != nil { - panic(err) - } - - if n < 1 { - return nil - } - - return &validatorpk.PubKey{ - Raw: crypto.FromECDSAPub(&makefakegenesis.FakeKey(n).PublicKey), - Type: validatorpk.Types.Secp256k1, - } -} diff --git a/evm/go-x1/cmd/opera/launcher/fixdirty.go b/evm/go-x1/cmd/opera/launcher/fixdirty.go deleted file mode 100644 index ef1a821..0000000 --- a/evm/go-x1/cmd/opera/launcher/fixdirty.go +++ /dev/null @@ -1,194 +0,0 @@ -package launcher - -import ( - "fmt" - "time" - - "github.com/Fantom-foundation/lachesis-base/abft" - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/batched" - "github.com/Fantom-foundation/lachesis-base/kvdb/flushable" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/integration" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" -) - -// maxEpochsToTry represents amount of last closed epochs to try (in case that the last one has the state unavailable) -const maxEpochsToTry = 10000 - -// healDirty is the 'db heal' command. -func healDirty(ctx *cli.Context) error { - if !ctx.Bool(experimentalFlag.Name) { - utils.Fatalf("Add --experimental flag") - } - cfg := makeAllConfigs(ctx) - - log.Info("Opening databases") - dbTypes := makeUncheckedDBsProducers(cfg) - multiProducer := makeDirectDBsProducerFrom(dbTypes, cfg) - - // reverts the gossip database state - epochState, topEpoch, err := fixDirtyGossipDb(multiProducer, cfg) - if err != nil { - return err - } - - // drop epoch-related databases and consensus database - log.Info("Removing epoch DBs - will be recreated on next start") - for _, name := range []string{ - fmt.Sprintf("gossip-%d", topEpoch), - fmt.Sprintf("lachesis-%d", topEpoch), - "lachesis", - } { - err = eraseTable(name, multiProducer) - if err != nil { - return err - } - } - - // prepare consensus database from epochState - log.Info("Recreating lachesis DB") - cMainDb := mustOpenDB(multiProducer, "lachesis") - cGetEpochDB := func(epoch idx.Epoch) kvdb.Store { - return mustOpenDB(multiProducer, fmt.Sprintf("lachesis-%d", epoch)) - } - cdb := abft.NewStore(cMainDb, cGetEpochDB, panics("Lachesis store"), cfg.LachesisStore) - err = cdb.ApplyGenesis(&abft.Genesis{ - Epoch: epochState.Epoch, - Validators: epochState.Validators, - }) - if err != nil { - return fmt.Errorf("failed to init consensus database: %v", err) - } - _ = cdb.Close() - - log.Info("Clearing DBs dirty flags") - id := bigendian.Uint64ToBytes(uint64(time.Now().UnixNano())) - for typ, producer := range dbTypes { - err := clearDirtyFlags(id, producer) - if err != nil { - log.Crit("Failed to write clean FlushID", "type", typ, "err", err) - } - } - - log.Info("Recovery is complete") - return nil -} - -// fixDirtyGossipDb reverts the gossip database into state, when was one of last epochs sealed -func fixDirtyGossipDb(producer kvdb.FlushableDBProducer, cfg *config) ( - epochState *iblockproc.EpochState, topEpoch idx.Epoch, err error) { - gdb := makeGossipStore(producer, cfg) // requires FlushIDKey present (not clean) in all dbs - defer gdb.Close() - topEpoch = gdb.GetEpoch() - - // find the last closed epoch with the state available - epochIdx, blockState, epochState := getLastEpochWithState(gdb, maxEpochsToTry) - if blockState == nil || epochState == nil { - return nil, 0, fmt.Errorf("state for last %d closed epochs is pruned, recovery isn't possible", maxEpochsToTry) - } - - // set the historic state to be the current - log.Info("Reverting to epoch state", "epoch", epochIdx) - gdb.SetBlockEpochState(*blockState, *epochState) - gdb.FlushBlockEpochState() - - // Service.switchEpochTo - gdb.SetHighestLamport(0) - gdb.FlushHighestLamport() - - // removing excessive events (event epoch >= closed epoch) - log.Info("Removing excessive events") - gdb.ForEachEventRLP(epochIdx.Bytes(), func(id hash.Event, _ rlp.RawValue) bool { - gdb.DelEvent(id) - return true - }) - - return epochState, topEpoch, nil -} - -// getLastEpochWithState finds the last closed epoch with the state available -func getLastEpochWithState(gdb *gossip.Store, epochsToTry idx.Epoch) (epochIdx idx.Epoch, blockState *iblockproc.BlockState, epochState *iblockproc.EpochState) { - currentEpoch := gdb.GetEpoch() - endEpoch := idx.Epoch(1) - if currentEpoch > epochsToTry { - endEpoch = currentEpoch - epochsToTry - } - - for epochIdx = currentEpoch; epochIdx > endEpoch; epochIdx-- { - blockState, epochState = gdb.GetHistoryBlockEpochState(epochIdx) - if blockState == nil || epochState == nil { - log.Debug("Epoch is not available", "epoch", epochIdx) - continue - } - if !gdb.EvmStore().HasStateDB(blockState.FinalizedStateRoot) { - log.Debug("EVM state for the epoch is not available", "epoch", epochIdx) - continue - } - log.Debug("Latest epoch with available state found", "epoch", epochIdx) - return epochIdx, blockState, epochState - } - - return 0, nil, nil -} - -func eraseTable(name string, producer kvdb.IterableDBProducer) error { - log.Info("Cleaning table", "name", name) - db, err := producer.OpenDB(name) - if err != nil { - return fmt.Errorf("unable to open DB %s; %s", name, err) - } - db = batched.Wrap(db) - defer db.Close() - it := db.NewIterator(nil, nil) - defer it.Release() - for it.Next() { - err := db.Delete(it.Key()) - if err != nil { - return err - } - } - return nil -} - -// clearDirtyFlags - writes the CleanPrefix into all databases -func clearDirtyFlags(id []byte, rawProducer kvdb.IterableDBProducer) error { - names := rawProducer.Names() - for _, name := range names { - db, err := rawProducer.OpenDB(name) - if err != nil { - return err - } - - err = db.Put(integration.FlushIDKey, append([]byte{flushable.CleanPrefix}, id...)) - if err != nil { - log.Crit("Failed to write CleanPrefix", "name", name) - return err - } - log.Info("Database set clean", "name", name) - _ = db.Close() - } - return nil -} - -func mustOpenDB(producer kvdb.DBProducer, name string) kvdb.Store { - db, err := producer.OpenDB(name) - if err != nil { - utils.Fatalf("Failed to open '%s' database: %v", name, err) - } - return db -} - -func panics(name string) func(error) { - return func(err error) { - log.Crit(fmt.Sprintf("%s error", name), "err", err) - } -} diff --git a/evm/go-x1/cmd/opera/launcher/genesiscmd.go b/evm/go-x1/cmd/opera/launcher/genesiscmd.go deleted file mode 100644 index 211126f..0000000 --- a/evm/go-x1/cmd/opera/launcher/genesiscmd.go +++ /dev/null @@ -1,404 +0,0 @@ -package launcher - -import ( - "compress/gzip" - "errors" - "fmt" - "io" - "math" - "os" - "path" - "strconv" - "strings" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/pebble" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/syndtr/goleveldb/leveldb/opt" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/opera/genesisstore" - "github.com/Fantom-foundation/go-opera/opera/genesisstore/fileshash" - "github.com/Fantom-foundation/go-opera/utils/devnullfile" - "github.com/Fantom-foundation/go-opera/utils/iodb" -) - -type dropableFile struct { - io.ReadWriteSeeker - io.Closer - path string -} - -func (f dropableFile) Drop() error { - return os.Remove(f.path) -} - -type mptIterator struct { - kvdb.Iterator -} - -func (it mptIterator) Next() bool { - for it.Iterator.Next() { - if evmstore.IsMptKey(it.Key()) { - return true - } - } - return false -} - -type mptAndPreimageIterator struct { - kvdb.Iterator -} - -func (it mptAndPreimageIterator) Next() bool { - for it.Iterator.Next() { - if evmstore.IsMptKey(it.Key()) || evmstore.IsPreimageKey(it.Key()) { - return true - } - } - return false -} - -type excludingIterator struct { - kvdb.Iterator - exclude kvdb.Reader -} - -func (it excludingIterator) Next() bool { - for it.Iterator.Next() { - if ok, _ := it.exclude.Has(it.Key()); !ok { - return true - } - } - return false -} - -type unitWriter struct { - plain io.WriteSeeker - gziper *gzip.Writer - fileshasher *fileshash.Writer - dataStartPos int64 - uncompressedSize uint64 -} - -func newUnitWriter(plain io.WriteSeeker) *unitWriter { - return &unitWriter{ - plain: plain, - } -} - -func (w *unitWriter) Start(header genesis.Header, name, tmpDirPath string) error { - if w.plain == nil { - // dry run - w.fileshasher = fileshash.WrapWriter(nil, genesisstore.FilesHashPieceSize, func(int) fileshash.TmpWriter { - return devnullfile.DevNull{} - }) - return nil - } - // Write unit marker and version - _, err := w.plain.Write(append(genesisstore.FileHeader, genesisstore.FileVersion...)) - if err != nil { - return err - } - - // write genesis header - err = rlp.Encode(w.plain, genesisstore.Unit{ - UnitName: name, - Header: header, - }) - if err != nil { - return err - } - - w.dataStartPos, err = w.plain.Seek(8+8+32, io.SeekCurrent) - if err != nil { - return err - } - - w.gziper, _ = gzip.NewWriterLevel(w.plain, gzip.BestCompression) - - w.fileshasher = fileshash.WrapWriter(w.gziper, genesisstore.FilesHashPieceSize, func(tmpI int) fileshash.TmpWriter { - tmpI++ - tmpPath := path.Join(tmpDirPath, fmt.Sprintf("genesis-%s-tmp-%d", name, tmpI)) - _ = os.MkdirAll(tmpDirPath, os.ModePerm) - tmpFh, err := os.OpenFile(tmpPath, os.O_CREATE|os.O_RDWR, os.ModePerm) - if err != nil { - log.Crit("File opening error", "path", tmpPath, "err", err) - } - return dropableFile{ - ReadWriteSeeker: tmpFh, - Closer: tmpFh, - path: tmpPath, - } - }) - return nil -} - -func (w *unitWriter) Flush() (hash.Hash, error) { - if w.plain == nil { - return w.fileshasher.Root(), nil - } - h, err := w.fileshasher.Flush() - if err != nil { - return hash.Hash{}, err - } - - err = w.gziper.Close() - if err != nil { - return hash.Hash{}, err - } - - endPos, err := w.plain.Seek(0, io.SeekCurrent) - if err != nil { - return hash.Hash{}, err - } - - _, err = w.plain.Seek(w.dataStartPos-(8+8+32), io.SeekStart) - if err != nil { - return hash.Hash{}, err - } - - _, err = w.plain.Write(h.Bytes()) - if err != nil { - return hash.Hash{}, err - } - _, err = w.plain.Write(bigendian.Uint64ToBytes(uint64(endPos - w.dataStartPos))) - if err != nil { - return hash.Hash{}, err - } - _, err = w.plain.Write(bigendian.Uint64ToBytes(w.uncompressedSize)) - if err != nil { - return hash.Hash{}, err - } - - _, err = w.plain.Seek(0, io.SeekEnd) - if err != nil { - return hash.Hash{}, err - } - return h, nil -} - -func (w *unitWriter) Write(b []byte) (n int, err error) { - n, err = w.fileshasher.Write(b) - w.uncompressedSize += uint64(n) - return -} - -func getEpochBlock(epoch idx.Epoch, store *gossip.Store) idx.Block { - bs, _ := store.GetHistoryBlockEpochState(epoch) - if bs == nil { - return 0 - } - return bs.LastBlock.Idx -} - -func exportGenesis(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { - utils.Fatalf("This command requires an argument.") - } - - from := idx.Epoch(1) - if len(ctx.Args()) > 1 { - n, err := strconv.ParseUint(ctx.Args().Get(1), 10, 32) - if err != nil { - return err - } - from = idx.Epoch(n) - } - to := idx.Epoch(math.MaxUint32) - if len(ctx.Args()) > 2 { - n, err := strconv.ParseUint(ctx.Args().Get(2), 10, 32) - if err != nil { - return err - } - to = idx.Epoch(n) - } - mode := ctx.String(EvmExportMode.Name) - if mode != "full" && mode != "ext-mpt" && mode != "mpt" { - return errors.New("--export.evm.mode must be one of {full, ext-mpt, mpt}") - } - - var excludeEvmDB kvdb.Store - if excludeEvmDBPath := ctx.String(EvmExportExclude.Name); len(excludeEvmDBPath) > 0 { - db, err := pebble.New(excludeEvmDBPath, 1024*opt.MiB, utils.MakeDatabaseHandles()/2, nil, nil) - if err != nil { - return err - } - excludeEvmDB = db - } - - sectionsStr := ctx.String(GenesisExportSections.Name) - sections := map[string]string{} - for _, str := range strings.Split(sectionsStr, ",") { - before := len(sections) - if strings.HasPrefix(str, "brs") { - sections["brs"] = str - } else if strings.HasPrefix(str, "ers") { - sections["ers"] = str - } else if strings.HasPrefix(str, "evm") { - sections["evm"] = str - } else { - return fmt.Errorf("unknown section '%s': has to start with either 'brs' or 'ers' or 'evm'", str) - } - if len(sections) == before { - return fmt.Errorf("duplicate section: '%s'", str) - } - } - - cfg := makeAllConfigs(ctx) - tmpPath := path.Join(cfg.Node.DataDir, "tmp") - _ = os.RemoveAll(tmpPath) - defer os.RemoveAll(tmpPath) - - rawDbs := makeDirectDBsProducer(cfg) - gdb := makeGossipStore(rawDbs, cfg) - if gdb.GetHighestLamport() != 0 { - log.Warn("Attempting genesis export not in a beginning of an epoch. Genesis file output may contain excessive data.") - } - defer gdb.Close() - - fn := ctx.Args().First() - - // Open the file handle - var plain io.WriteSeeker - if fn != "dry-run" { - fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) - if err != nil { - return err - } - defer fh.Close() - plain = fh - } - - header := genesis.Header{ - GenesisID: *gdb.GetGenesisID(), - NetworkID: gdb.GetEpochState().Rules.NetworkID, - NetworkName: gdb.GetEpochState().Rules.Name, - } - var epochsHash hash.Hash - var blocksHash hash.Hash - var evmHash hash.Hash - - if from < 1 { - // avoid underflow - from = 1 - } - if to > gdb.GetEpoch() { - to = gdb.GetEpoch() - } - if len(sections["ers"]) > 0 { - log.Info("Exporting epochs", "from", from, "to", to) - writer := newUnitWriter(plain) - err := writer.Start(header, sections["ers"], tmpPath) - if err != nil { - return err - } - for i := to; i >= from; i-- { - er := gdb.GetFullEpochRecord(i) - if er == nil { - log.Warn("No epoch record", "epoch", i) - break - } - b, _ := rlp.EncodeToBytes(ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: *er, - Idx: i, - }) - _, err := writer.Write(b) - if err != nil { - return err - } - } - epochsHash, err = writer.Flush() - if err != nil { - return err - } - log.Info("Exported epochs") - fmt.Printf("- Epochs hash: %v \n", epochsHash.String()) - } - - if len(sections["brs"]) > 0 { - toBlock := getEpochBlock(to, gdb) - fromBlock := getEpochBlock(from, gdb) - if sections["brs"] != "brs" { - // to continue prev section, include blocks of prev epochs too, excluding first blocks of prev epoch (which is last block if prev section) - fromBlock = getEpochBlock(from-1, gdb) + 1 - } - if fromBlock < 1 { - // avoid underflow - fromBlock = 1 - } - log.Info("Exporting blocks", "from", fromBlock, "to", toBlock) - writer := newUnitWriter(plain) - err := writer.Start(header, sections["brs"], tmpPath) - if err != nil { - return err - } - for i := toBlock; i >= fromBlock; i-- { - br := gdb.GetFullBlockRecord(i) - if br == nil { - log.Warn("No block record", "block", i) - break - } - if i%200000 == 0 { - log.Info("Exporting blocks", "last", i) - } - b, _ := rlp.EncodeToBytes(ibr.LlrIdxFullBlockRecord{ - LlrFullBlockRecord: *br, - Idx: i, - }) - _, err := writer.Write(b) - if err != nil { - return err - } - } - blocksHash, err = writer.Flush() - if err != nil { - return err - } - log.Info("Exported blocks") - fmt.Printf("- Blocks hash: %v \n", blocksHash.String()) - } - - if len(sections["evm"]) > 0 { - log.Info("Exporting EVM data") - writer := newUnitWriter(plain) - err := writer.Start(header, sections["evm"], tmpPath) - if err != nil { - return err - } - it := gdb.EvmStore().EvmDb.NewIterator(nil, nil) - if mode == "mpt" { - // iterate only over MPT data - it = mptIterator{it} - } else if mode == "ext-mpt" { - // iterate only over MPT data and preimages - it = mptAndPreimageIterator{it} - } - if excludeEvmDB != nil { - it = excludingIterator{it, excludeEvmDB} - } - defer it.Release() - err = iodb.Write(writer, it) - if err != nil { - return err - } - evmHash, err = writer.Flush() - if err != nil { - return err - } - log.Info("Exported EVM data") - fmt.Printf("- EVM hash: %v \n", evmHash.String()) - } - - return nil -} diff --git a/evm/go-x1/cmd/opera/launcher/import.go b/evm/go-x1/cmd/opera/launcher/import.go deleted file mode 100644 index 4fe3ded..0000000 --- a/evm/go-x1/cmd/opera/launcher/import.go +++ /dev/null @@ -1,239 +0,0 @@ -package launcher - -import ( - "bytes" - "compress/gzip" - "errors" - "fmt" - "io" - "math" - "os" - "os/signal" - "strings" - "syscall" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/status-im/keycard-go/hexutils" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera/genesisstore" - "github.com/Fantom-foundation/go-opera/utils/ioread" -) - -func importEvm(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { - utils.Fatalf("This command requires an argument.") - } - - cfg := makeAllConfigs(ctx) - - rawDbs := makeDirectDBsProducer(cfg) - gdb := makeGossipStore(rawDbs, cfg) - defer gdb.Close() - - for _, fn := range ctx.Args() { - log.Info("Importing EVM storage from file", "file", fn) - if err := importEvmFile(fn, gdb); err != nil { - log.Error("Import error", "file", fn, "err", err) - return err - } - log.Info("Imported EVM storage from file", "file", fn) - } - - return nil -} - -func importEvmFile(fn string, gdb *gossip.Store) error { - // Open the file handle and potentially unwrap the gzip stream - fh, err := os.Open(fn) - if err != nil { - return err - } - defer fh.Close() - - var reader io.Reader = fh - if strings.HasSuffix(fn, ".gz") { - if reader, err = gzip.NewReader(reader); err != nil { - return err - } - defer reader.(*gzip.Reader).Close() - } - - return gdb.EvmStore().ImportEvm(reader) -} - -func importEvents(ctx *cli.Context) error { - if len(ctx.Args()) < 1 { - utils.Fatalf("This command requires an argument.") - } - - // avoid P2P interaction, API calls and events emitting - genesisStore := mayGetGenesisStore(ctx) - cfg := makeAllConfigs(ctx) - cfg.Opera.Protocol.EventsSemaphoreLimit.Size = math.MaxUint32 - cfg.Opera.Protocol.EventsSemaphoreLimit.Num = math.MaxUint32 - cfg.Emitter.Validator = emitter.ValidatorConfig{} - cfg.TxPool.Journal = "" - cfg.Node.IPCPath = "" - cfg.Node.HTTPHost = "" - cfg.Node.WSHost = "" - cfg.Node.NoUSB = true - cfg.Node.P2P.ListenAddr = "" - cfg.Node.P2P.NoDiscovery = true - cfg.Node.P2P.BootstrapNodes = nil - cfg.Node.P2P.DiscoveryV5 = false - cfg.Node.P2P.BootstrapNodesV5 = nil - cfg.Node.P2P.StaticNodes = nil - cfg.Node.P2P.TrustedNodes = nil - - err := importEventsToNode(ctx, cfg, genesisStore, ctx.Args()...) - if err != nil { - return err - } - - return nil -} - -func importEventsToNode(ctx *cli.Context, cfg *config, genesisStore *genesisstore.Store, args ...string) error { - node, svc, nodeClose := makeNode(ctx, cfg, genesisStore) - defer nodeClose() - startNode(ctx, node) - - for _, fn := range args { - log.Info("Importing events from file", "file", fn) - if err := importEventsFile(svc, fn); err != nil { - log.Error("Import error", "file", fn, "err", err) - return err - } - } - return nil -} - -func checkEventsFileHeader(reader io.Reader) error { - headerAndVersion := make([]byte, len(eventsFileHeader)+len(eventsFileVersion)) - err := ioread.ReadAll(reader, headerAndVersion) - if err != nil { - return err - } - if bytes.Compare(headerAndVersion[:len(eventsFileHeader)], eventsFileHeader) != 0 { - return errors.New("expected an events file, mismatched file header") - } - if bytes.Compare(headerAndVersion[len(eventsFileHeader):], eventsFileVersion) != 0 { - got := hexutils.BytesToHex(headerAndVersion[len(eventsFileHeader):]) - expected := hexutils.BytesToHex(eventsFileVersion) - return errors.New(fmt.Sprintf("wrong version of events file, got=%s, expected=%s", got, expected)) - } - return nil -} - -func importEventsFile(srv *gossip.Service, fn string) error { - // Watch for Ctrl-C while the import is running. - // If a signal is received, the import will stop. - interrupt := make(chan os.Signal, 1) - signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM) - defer signal.Stop(interrupt) - - // wait until snapshot generation is complete - for srv.EvmSnapshotGeneration() { - select { - case <-interrupt: - return fmt.Errorf("interrupted") - case <-time.After(100 * time.Millisecond): - continue - } - } - - // Open the file handle and potentially unwrap the gzip stream - fh, err := os.Open(fn) - if err != nil { - return err - } - defer fh.Close() - - var reader io.Reader = fh - if strings.HasSuffix(fn, ".gz") { - if reader, err = gzip.NewReader(reader); err != nil { - return err - } - defer reader.(*gzip.Reader).Close() - } - - // Check file version and header - if err := checkEventsFileHeader(reader); err != nil { - return err - } - - stream := rlp.NewStream(reader, 0) - - start := time.Now() - last := hash.Event{} - - batch := make(inter.EventPayloads, 0, 8*1024) - batchSize := 0 - maxBatchSize := 8 * 1024 * 1024 - epoch := idx.Epoch(0) - txs := 0 - events := 0 - - processBatch := func() error { - if batch.Len() == 0 { - return nil - } - done := make(chan struct{}) - err := srv.DagProcessor().Enqueue("", batch.Bases(), true, nil, func() { - done <- struct{}{} - }) - if err != nil { - return err - } - <-done - last = batch[batch.Len()-1].ID() - batch = batch[:0] - batchSize = 0 - return nil - } - - for { - select { - case <-interrupt: - return fmt.Errorf("interrupted") - default: - } - e := new(inter.EventPayload) - err = stream.Decode(e) - if err == io.EOF { - err = processBatch() - if err != nil { - return err - } - break - } - if err != nil { - return err - } - if e.Epoch() != epoch || batchSize >= maxBatchSize { - err = processBatch() - if err != nil { - return err - } - } - epoch = e.Epoch() - batch = append(batch, e) - batchSize += 1024 + e.Size() - txs += e.Txs().Len() - events++ - } - srv.WaitBlockEnd() - log.Info("Events import is finished", "file", fn, "last", last.String(), "imported", events, "txs", txs, "elapsed", common.PrettyDuration(time.Since(start))) - - return nil -} diff --git a/evm/go-x1/cmd/opera/launcher/launcher.go b/evm/go-x1/cmd/opera/launcher/launcher.go deleted file mode 100644 index caffa79..0000000 --- a/evm/go-x1/cmd/opera/launcher/launcher.go +++ /dev/null @@ -1,478 +0,0 @@ -package launcher - -import ( - "fmt" - "path" - "sort" - "strings" - "time" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/console/prompt" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/log" - gmetrics "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p/discover/discfilter" - "github.com/ethereum/go-ethereum/params" - "gopkg.in/urfave/cli.v1" - - evmetrics "github.com/ethereum/go-ethereum/metrics" - - "github.com/Fantom-foundation/go-opera/cmd/opera/launcher/metrics" - "github.com/Fantom-foundation/go-opera/cmd/opera/launcher/tracing" - "github.com/Fantom-foundation/go-opera/debug" - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/flags" - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/integration" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/opera/genesisstore" - "github.com/Fantom-foundation/go-opera/utils/errlock" - "github.com/Fantom-foundation/go-opera/valkeystore" - _ "github.com/Fantom-foundation/go-opera/version" -) - -const ( - // clientIdentifier to advertise over the network. - clientIdentifier = "go-x1" -) - -var ( - // Git SHA1 commit hash of the release (set via linker flags). - gitCommit = "" - gitDate = "" - // The app that holds all commands and flags. - app = flags.NewApp(gitCommit, gitDate, "the go-x1 command line interface") - - nodeFlags []cli.Flag - testFlags []cli.Flag - gpoFlags []cli.Flag - accountFlags []cli.Flag - performanceFlags []cli.Flag - networkingFlags []cli.Flag - txpoolFlags []cli.Flag - operaFlags []cli.Flag - legacyRpcFlags []cli.Flag - rpcFlags []cli.Flag - metricsFlags []cli.Flag -) - -func initFlags() { - // Flags for testing purpose. - testFlags = []cli.Flag{ - FakeNetFlag, - TestnetFlag, - } - - // Flags that configure the node. - gpoFlags = []cli.Flag{} - accountFlags = []cli.Flag{ - utils.UnlockedAccountFlag, - utils.PasswordFileFlag, - utils.ExternalSignerFlag, - utils.InsecureUnlockAllowedFlag, - } - performanceFlags = []cli.Flag{ - CacheFlag, - } - networkingFlags = []cli.Flag{ - utils.BootnodesFlag, - utils.ListenPortFlag, - utils.MaxPeersFlag, - utils.MaxPendingPeersFlag, - utils.NATFlag, - utils.NoDiscoverFlag, - utils.DiscoveryV5Flag, - utils.NetrestrictFlag, - utils.IPrestrictFlag, - utils.PrivateNodeFlag, - utils.NodeKeyFileFlag, - utils.NodeKeyHexFlag, - } - txpoolFlags = []cli.Flag{ - utils.TxPoolLocalsFlag, - utils.TxPoolNoLocalsFlag, - utils.TxPoolJournalFlag, - utils.TxPoolRejournalFlag, - utils.TxPoolPriceLimitFlag, - utils.TxPoolPriceBumpFlag, - utils.TxPoolAccountSlotsFlag, - utils.TxPoolGlobalSlotsFlag, - utils.TxPoolAccountQueueFlag, - utils.TxPoolGlobalQueueFlag, - utils.TxPoolLifetimeFlag, - } - operaFlags = []cli.Flag{ - GenesisFlag, - ExperimentalGenesisFlag, - utils.IdentityFlag, - DataDirFlag, - utils.MinFreeDiskSpaceFlag, - utils.KeyStoreDirFlag, - utils.USBFlag, - utils.SmartCardDaemonPathFlag, - ExitWhenAgeFlag, - ExitWhenEpochFlag, - utils.LightKDFFlag, - configFileFlag, - validatorIDFlag, - validatorPubkeyFlag, - validatorPasswordFlag, - SyncModeFlag, - GCModeFlag, - DBPresetFlag, - DBMigrationModeFlag, - } - legacyRpcFlags = []cli.Flag{ - utils.NoUSBFlag, - utils.LegacyRPCEnabledFlag, - utils.LegacyRPCListenAddrFlag, - utils.LegacyRPCPortFlag, - utils.LegacyRPCCORSDomainFlag, - utils.LegacyRPCVirtualHostsFlag, - utils.LegacyRPCApiFlag, - } - - rpcFlags = []cli.Flag{ - utils.HTTPEnabledFlag, - utils.HTTPListenAddrFlag, - utils.HTTPPortFlag, - utils.HTTPCORSDomainFlag, - utils.HTTPVirtualHostsFlag, - utils.GraphQLEnabledFlag, - utils.GraphQLCORSDomainFlag, - utils.GraphQLVirtualHostsFlag, - utils.HTTPApiFlag, - utils.HTTPPathPrefixFlag, - utils.WSEnabledFlag, - utils.WSListenAddrFlag, - utils.WSPortFlag, - utils.WSApiFlag, - utils.WSAllowedOriginsFlag, - utils.WSPathPrefixFlag, - utils.IPCDisabledFlag, - utils.IPCPathFlag, - RPCGlobalGasCapFlag, - RPCGlobalEVMTimeoutFlag, - RPCGlobalTxFeeCapFlag, - RPCGlobalTimeoutFlag, - } - - metricsFlags = []cli.Flag{ - utils.MetricsEnabledFlag, - utils.MetricsEnabledExpensiveFlag, - utils.MetricsHTTPFlag, - utils.MetricsPortFlag, - utils.MetricsEnableInfluxDBFlag, - utils.MetricsInfluxDBEndpointFlag, - utils.MetricsInfluxDBDatabaseFlag, - utils.MetricsInfluxDBUsernameFlag, - utils.MetricsInfluxDBPasswordFlag, - utils.MetricsInfluxDBTagsFlag, - utils.MetricsEnableInfluxDBV2Flag, - utils.MetricsInfluxDBTokenFlag, - utils.MetricsInfluxDBBucketFlag, - utils.MetricsInfluxDBOrganizationFlag, - tracing.EnableFlag, - } - - nodeFlags = []cli.Flag{} - nodeFlags = append(nodeFlags, gpoFlags...) - nodeFlags = append(nodeFlags, accountFlags...) - nodeFlags = append(nodeFlags, performanceFlags...) - nodeFlags = append(nodeFlags, networkingFlags...) - nodeFlags = append(nodeFlags, txpoolFlags...) - nodeFlags = append(nodeFlags, operaFlags...) - nodeFlags = append(nodeFlags, legacyRpcFlags...) -} - -// init the CLI app. -func init() { - discfilter.Enable() - overrideFlags() - overrideParams() - - initFlags() - - // App. - - app.Action = lachesisMain - app.Version = params.VersionWithCommit(gitCommit, gitDate) - app.HideVersion = true // we have a command to print the version - app.Commands = []cli.Command{ - // See accountcmd.go: - accountCommand, - walletCommand, - // see validatorcmd.go: - validatorCommand, - // See consolecmd.go: - consoleCommand, - attachCommand, - javascriptCommand, - // See config.go: - dumpConfigCommand, - checkConfigCommand, - // See misccmd.go: - versionCommand, - licenseCommand, - // See chaincmd.go - importCommand, - exportCommand, - checkCommand, - // See snapshot.go - snapshotCommand, - // See dbcmd.go - dbCommand, - } - sort.Sort(cli.CommandsByName(app.Commands)) - - app.Flags = append(app.Flags, testFlags...) - app.Flags = append(app.Flags, nodeFlags...) - app.Flags = append(app.Flags, rpcFlags...) - app.Flags = append(app.Flags, consoleFlags...) - app.Flags = append(app.Flags, debug.Flags...) - app.Flags = append(app.Flags, metricsFlags...) - - app.Before = func(ctx *cli.Context) error { - if err := debug.Setup(ctx); err != nil { - return err - } - - // Start metrics export if enabled - utils.SetupMetrics(ctx) - // Start system runtime metrics collection - go evmetrics.CollectProcessMetrics(3 * time.Second) - return nil - } - - app.After = func(ctx *cli.Context) error { - debug.Exit() - prompt.Stdin.Close() // Resets terminal mode. - - return nil - } -} - -func Launch(args []string) error { - return app.Run(args) -} - -// opera is the main entry point into the system if no special subcommand is ran. -// It creates a default node based on the command line arguments and runs it in -// blocking mode, waiting for it to be shut down. -func lachesisMain(ctx *cli.Context) error { - if args := ctx.Args(); len(args) > 0 { - return fmt.Errorf("invalid command: %q", args[0]) - } - - // TODO: tracing flags - //tracingStop, err := tracing.Start(ctx) - //if err != nil { - // return err - //} - //defer tracingStop() - - cfg := makeAllConfigs(ctx) - genesisStore := mayGetGenesisStore(ctx) - node, _, nodeClose := makeNode(ctx, cfg, genesisStore) - defer nodeClose() - startNode(ctx, node) - node.Wait() - return nil -} - -func makeNode(ctx *cli.Context, cfg *config, genesisStore *genesisstore.Store) (*node.Node, *gossip.Service, func()) { - // check errlock file - errlock.SetDefaultDatadir(cfg.Node.DataDir) - errlock.Check() - - var g *genesis.Genesis - if genesisStore != nil { - gv := genesisStore.Genesis() - g = &gv - } - - engine, dagIndex, gdb, cdb, blockProc, closeDBs := integration.MakeEngine(path.Join(cfg.Node.DataDir, "chaindata"), g, cfg.AppConfigs()) - if genesisStore != nil { - _ = genesisStore.Close() - } - - if gmetrics.Enabled { - metrics.SetDataDir(cfg.Node.DataDir) - } - memorizeDBPreset(cfg) - - // substitute default bootnodes if requested - networkName := "" - if gdb.HasBlockEpochState() { - networkName = gdb.GetRules().Name - } - if len(networkName) == 0 && genesisStore != nil { - networkName = genesisStore.Header().NetworkName - } - if needDefaultBootnodes(cfg.Node.P2P.BootstrapNodes) { - bootnodes := Bootnodes[networkName] - if bootnodes == nil { - bootnodes = []string{} - } - setBootnodes(ctx, bootnodes, &cfg.Node) - } - - stack := makeConfigNode(ctx, &cfg.Node) - - valKeystore := valkeystore.NewDefaultFileKeystore(path.Join(getValKeystoreDir(cfg.Node), "validator")) - valPubkey := cfg.Emitter.Validator.PubKey - if key := getFakeValidatorKey(ctx); key != nil && cfg.Emitter.Validator.ID != 0 { - addFakeValidatorKey(ctx, key, valPubkey, valKeystore) - coinbase := integration.SetAccountKey(stack.AccountManager(), key, "fakepassword") - log.Info("Unlocked fake validator account", "address", coinbase.Address.Hex()) - } - - // unlock validator key - if !valPubkey.Empty() { - err := unlockValidatorKey(ctx, valPubkey, valKeystore) - if err != nil { - utils.Fatalf("Failed to unlock validator key: %v", err) - } - } - signer := valkeystore.NewSigner(valKeystore) - - // Create and register a gossip network service. - newTxPool := func(reader evmcore.StateReader) gossip.TxPool { - if cfg.TxPool.Journal != "" { - cfg.TxPool.Journal = stack.ResolvePath(cfg.TxPool.Journal) - } - return evmcore.NewTxPool(cfg.TxPool, reader.Config(), reader) - } - haltCheck := func(oldEpoch, newEpoch idx.Epoch, age time.Time) bool { - stop := ctx.GlobalIsSet(ExitWhenAgeFlag.Name) && ctx.GlobalDuration(ExitWhenAgeFlag.Name) >= time.Since(age) - stop = stop || ctx.GlobalIsSet(ExitWhenEpochFlag.Name) && idx.Epoch(ctx.GlobalUint64(ExitWhenEpochFlag.Name)) <= newEpoch - if stop { - go func() { - // do it in a separate thread to avoid deadlock - _ = stack.Close() - }() - return true - } - return false - } - svc, err := gossip.NewService(stack, cfg.Opera, gdb, blockProc, engine, dagIndex, newTxPool, haltCheck) - if err != nil { - utils.Fatalf("Failed to create the service: %v", err) - } - err = engine.StartFrom(svc.GetConsensusCallbacks(), gdb.GetEpoch(), gdb.GetValidators()) - if err != nil { - utils.Fatalf("Failed to start the engine: %v", err) - } - svc.ReprocessEpochEvents() - if cfg.Emitter.Validator.ID != 0 { - svc.RegisterEmitter(emitter.NewEmitter(cfg.Emitter, svc.EmitterWorld(signer))) - } - - stack.RegisterAPIs(svc.APIs()) - stack.RegisterProtocols(svc.Protocols()) - stack.RegisterLifecycle(svc) - - return stack, svc, func() { - _ = stack.Close() - gdb.Close() - _ = cdb.Close() - if closeDBs != nil { - _ = closeDBs() - } - } -} - -func makeConfigNode(ctx *cli.Context, cfg *node.Config) *node.Node { - stack, err := node.New(cfg) - if err != nil { - utils.Fatalf("Failed to create the protocol stack: %v", err) - } - - return stack -} - -// startNode boots up the system node and all registered protocols, after which -// it unlocks any requested accounts, and starts the RPC/IPC interfaces. -func startNode(ctx *cli.Context, stack *node.Node) { - debug.Memsize.Add("node", stack) - - // Start up the node itself - utils.StartNode(ctx, stack) - - // Unlock any account specifically requested - unlockAccounts(ctx, stack) - - // Register wallet event handlers to open and auto-derive wallets - events := make(chan accounts.WalletEvent, 16) - stack.AccountManager().Subscribe(events) - - // Create a client to interact with local opera node. - rpcClient, err := stack.Attach() - if err != nil { - utils.Fatalf("Failed to attach to self: %v", err) - } - ethClient := ethclient.NewClient(rpcClient) - go func() { - // Open any wallets already attached - for _, wallet := range stack.AccountManager().Wallets() { - if err := wallet.Open(""); err != nil { - log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err) - } - } - // Listen for wallet event till termination - for event := range events { - switch event.Kind { - case accounts.WalletArrived: - if err := event.Wallet.Open(""); err != nil { - log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err) - } - case accounts.WalletOpened: - status, _ := event.Wallet.Status() - log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) - - var derivationPaths []accounts.DerivationPath - if event.Wallet.URL().Scheme == "ledger" { - derivationPaths = append(derivationPaths, accounts.LegacyLedgerBaseDerivationPath) - } - derivationPaths = append(derivationPaths, accounts.DefaultBaseDerivationPath) - - event.Wallet.SelfDerive(derivationPaths, ethClient) - - case accounts.WalletDropped: - log.Info("Old wallet dropped", "url", event.Wallet.URL()) - event.Wallet.Close() - } - } - }() -} - -// unlockAccounts unlocks any account specifically requested. -func unlockAccounts(ctx *cli.Context, stack *node.Node) { - var unlocks []string - inputs := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") - for _, input := range inputs { - if trimmed := strings.TrimSpace(input); trimmed != "" { - unlocks = append(unlocks, trimmed) - } - } - // Short circuit if there is no account to unlock. - if len(unlocks) == 0 { - return - } - // If insecure account unlocking is not allowed if node's APIs are exposed to external. - // Print warning log to user and skip unlocking. - if !stack.Config().InsecureUnlockAllowed && stack.Config().ExtRPCEnabled() { - utils.Fatalf("Account unlock with HTTP access is forbidden!") - } - ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) - passwords := utils.MakePasswordList(ctx) - for i, account := range unlocks { - unlockAccount(ks, account, i, passwords) - } -} diff --git a/evm/go-x1/cmd/opera/launcher/metrics/metrics.go b/evm/go-x1/cmd/opera/launcher/metrics/metrics.go deleted file mode 100644 index 7daa782..0000000 --- a/evm/go-x1/cmd/opera/launcher/metrics/metrics.go +++ /dev/null @@ -1,78 +0,0 @@ -package metrics - -import ( - "os" - "path/filepath" - "sync" - "sync/atomic" - "time" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" -) - -var once sync.Once - -func SetDataDir(datadir string) { - once.Do(func() { - go measureDbDir("db_size", datadir) - }) -} - -func measureDbDir(name, datadir string) { - var ( - dbSize int64 - gauge metrics.Gauge - rescan = (len(datadir) > 0 && datadir != "inmemory") - ) - for { - time.Sleep(10 * time.Second) - - if rescan { - size := sizeOfDir(datadir, new(int)) - atomic.StoreInt64(&dbSize, size) - } - - if gauge == nil { - gauge = metrics.NewRegisteredFunctionalGauge(name, nil, func() int64 { - return atomic.LoadInt64(&dbSize) - }) - } - - if !rescan { - break - } - } -} - -func sizeOfDir(dir string, counter *int) (size int64) { - err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - *counter++ - if *counter % 100 == 0 { - time.Sleep(100 * time.Millisecond) - } - if err != nil { - log.Debug("datadir walk", "path", path, "err", err) - return filepath.SkipDir - } - - if info.IsDir() { - return nil - } - - dst, err := filepath.EvalSymlinks(path) - if err == nil && dst != path { - size += sizeOfDir(dst, counter) - } else { - size += info.Size() - } - - return nil - }) - - if err != nil { - log.Debug("datadir walk", "path", dir, "err", err) - } - - return -} diff --git a/evm/go-x1/cmd/opera/launcher/misccmd.go b/evm/go-x1/cmd/opera/launcher/misccmd.go deleted file mode 100644 index eae5f93..0000000 --- a/evm/go-x1/cmd/opera/launcher/misccmd.go +++ /dev/null @@ -1,59 +0,0 @@ -package launcher - -import ( - "fmt" - "os" - "runtime" - "strings" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/params" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/gossip" -) - -var ( - versionCommand = cli.Command{ - Action: utils.MigrateFlags(version), - Name: "version", - Usage: "Print version numbers", - ArgsUsage: " ", - Category: "MISCELLANEOUS COMMANDS", - Description: ` -The output of this command is supposed to be machine-readable. -`, - } - - licenseCommand = cli.Command{ - Action: utils.MigrateFlags(license), - Name: "license", - Usage: "Display license information", - ArgsUsage: " ", - Category: "MISCELLANEOUS COMMANDS", - } -) - -func version(ctx *cli.Context) error { - fmt.Println(strings.Title(clientIdentifier)) - fmt.Println("Version:", params.VersionWithMeta()) - if gitCommit != "" { - fmt.Println("Git Commit:", gitCommit) - } - if gitDate != "" { - fmt.Println("Git Commit Date:", gitDate) - } - fmt.Println("Architecture:", runtime.GOARCH) - fmt.Println("Protocol Versions:", []uint{gossip.ProtocolVersion}) - fmt.Println("Go Version:", runtime.Version()) - fmt.Println("Operating System:", runtime.GOOS) - fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) - fmt.Printf("GOROOT=%s\n", runtime.GOROOT()) - return nil -} - -func license(_ *cli.Context) error { - // TODO: license text - fmt.Println(``) - return nil -} diff --git a/evm/go-x1/cmd/opera/launcher/params.go b/evm/go-x1/cmd/opera/launcher/params.go deleted file mode 100644 index fa5da04..0000000 --- a/evm/go-x1/cmd/opera/launcher/params.go +++ /dev/null @@ -1,46 +0,0 @@ -package launcher - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/opera/genesisstore" -) - -var ( - Bootnodes = map[string][]string{ - "main": {}, - "x1-testnet": { - "enode://9ed669d0c35cc4eb7aba930d8c05b5ad8ff0e3318ad1c3c5f81ae6241b40698ef4146b2a9ac80343130df2e83f137f78648565fd810b090595c0b8b4b4123a48@34.211.87.93:5050", - "enode://c03ae9cb7a3485aba9ae3945944fad9bc678bc362bf13741033511f689df7f22063b312fac900f3fcf2ef3792e6312a84204842964085a7f0b44f4c850500405@35.155.140.94:5050", - "enode://db70d9620aeb252d18cd7309405393921da47acf2e13cd1559b190bcc5d554bf6a75c2675c2f9bb29710dcb48ae94ef9b9abe9a9baf5ab7348c35e53f3c47c8c@44.224.180.169:5050", - }, - } - - testnetHeader = genesis.Header{ - GenesisID: hash.HexToHash("0x4c4fdf6346c8851355eb305399d05036a0512aea15d1cb9b364a353704d5fbcb"), - NetworkID: opera.TestNetworkID, - NetworkName: "x1-testnet", - } - - AllowedOperaGenesis = []GenesisTemplate{ - { - Name: "x1-testnet with full MPT", - Header: testnetHeader, - Hashes: genesis.Hashes{ - genesisstore.EpochsSection(0): hash.HexToHash("0xe4c9d47ea5aac4beaac9655c8e63257762f1a4bc4e55028765d7b791392beba7"), - genesisstore.BlocksSection(0): hash.HexToHash("0xc3163030010b8a02bdce6dbb8d6dacb2e9d9a136c3afe03a4700df6473e8252a"), - genesisstore.EvmSection(0): hash.HexToHash("0x48c9563f4c42333b1c8c0a6feccd839c5feb3c9507e334ddb088fc2ee67b4641"), - }, - }, - } -) - -func overrideParams() { - params.MainnetBootnodes = []string{} - params.RopstenBootnodes = []string{} - params.RinkebyBootnodes = []string{} - params.GoerliBootnodes = []string{} -} diff --git a/evm/go-x1/cmd/opera/launcher/run_test.go b/evm/go-x1/cmd/opera/launcher/run_test.go deleted file mode 100644 index 0e52480..0000000 --- a/evm/go-x1/cmd/opera/launcher/run_test.go +++ /dev/null @@ -1,124 +0,0 @@ -package launcher - -import ( - "context" - "fmt" - "io/ioutil" - "os" - "strings" - "testing" - "time" - - "github.com/docker/docker/pkg/reexec" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rpc" - - "github.com/Fantom-foundation/go-opera/cmd/cmdtest" -) - -func tmpdir(t *testing.T) string { - dir, err := ioutil.TempDir("", "opera-test") - if err != nil { - t.Fatal(err) - } - return dir -} - -type testcli struct { - *cmdtest.TestCmd - - // template variables for expect - Datadir string - Coinbase string -} - -func (tt *testcli) readConfig() { - cfg := defaultNodeConfig() - cfg.DataDir = tt.Datadir - addr := common.Address{} // TODO: addr = emitter coinbase - tt.Coinbase = strings.ToLower(addr.String()) -} - -func init() { - // Run the app if we've been exec'd as "opera-test" in exec(). - reexec.Register("opera-test", func() { - if err := app.Run(os.Args); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - os.Exit(0) - }) -} - -func TestMain(m *testing.M) { - // check if we have been reexec'd - if reexec.Init() { - return - } - os.Exit(m.Run()) -} - -// exec cli with the given command line args. If the args don't set --datadir, the -// child g gets a temporary data directory. -func exec(t *testing.T, args ...string) *testcli { - tt := &testcli{} - tt.TestCmd = cmdtest.NewTestCmd(t, tt) - - if len(args) < 1 || args[0] != "attach" { - // make datadir - for i, arg := range args { - switch { - case arg == "-datadir" || arg == "--datadir": - if i < len(args)-1 { - tt.Datadir = args[i+1] - } - } - } - if tt.Datadir == "" { - tt.Datadir = tmpdir(t) - args = append([]string{"-datadir", tt.Datadir}, args...) - } - - // Remove the temporary datadir. - tt.Cleanup = func() { os.RemoveAll(tt.Datadir) } - defer func() { - if t.Failed() { - tt.Cleanup() - } - }() - } - - // Boot "opera". This actually runs the test binary but the TestMain - // function will prevent any tests from running. - tt.Run("opera-test", args...) - - // Read the generated key - tt.readConfig() - - return tt -} - -// waitForEndpoint attempts to connect to an RPC endpoint until it succeeds. -func waitForEndpoint(t *testing.T, endpoint string, timeout time.Duration) { - probe := func() bool { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - c, err := rpc.DialContext(ctx, endpoint) - if c != nil { - _, err = c.SupportedModules() - c.Close() - } - return err == nil - } - - start := time.Now() - for { - if probe() { - return - } - if time.Since(start) > timeout { - t.Fatal("endpoint", endpoint, "did not open within", timeout) - } - time.Sleep(200 * time.Millisecond) - } -} diff --git a/evm/go-x1/cmd/opera/launcher/snapshotcmd.go b/evm/go-x1/cmd/opera/launcher/snapshotcmd.go deleted file mode 100644 index b20d277..0000000 --- a/evm/go-x1/cmd/opera/launcher/snapshotcmd.go +++ /dev/null @@ -1,477 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -package launcher - -import ( - "bytes" - "errors" - "os" - "path" - "time" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/gossip/evmstore/evmpruner" -) - -var ( - PruneExactCommand = cli.BoolFlag{ - Name: "prune.exact", - Usage: `full pruning without usage of bloom filter (false by default)`, - } - PruneGenesisCommand = cli.BoolTFlag{ - Name: "prune.genesis", - Usage: `prune genesis state (true by default)`, - } - snapshotCommand = cli.Command{ - Name: "snapshot", - Usage: "A set of commands based on the snapshot", - Category: "MISCELLANEOUS COMMANDS", - Description: "", - Subcommands: []cli.Command{ - { - Name: "prune-state", - Usage: "Prune stale EVM state data based on the snapshot", - ArgsUsage: " [--prune.exact] [--prune.genesis=false]", - Action: utils.MigrateFlags(pruneState), - Category: "MISCELLANEOUS COMMANDS", - Flags: []cli.Flag{ - PruneExactCommand, - PruneGenesisCommand, - DataDirFlag, - utils.AncientFlag, - utils.RopstenFlag, - utils.RinkebyFlag, - utils.GoerliFlag, - utils.CacheTrieJournalFlag, - utils.BloomFilterSizeFlag, - }, - Description: ` -geth snapshot prune-state -will prune historical state data with the help of the state snapshot. -All trie nodes and contract codes that do not belong to the specified -version state will be deleted from the database. After pruning, only -two version states are available: genesis and the specific one. - -The default pruning target is the HEAD state. - -WARNING: It's necessary to delete the trie clean cache after the pruning. -If you specify another directory for the trie clean cache via "--cache.trie.journal" -during the use of Geth, please also specify it here for correct deletion. Otherwise -the trie clean cache with default directory will be deleted. -`, - }, - { - Name: "verify-state", - Usage: "Recalculate state hash based on the snapshot for verification", - ArgsUsage: "", - Action: utils.MigrateFlags(verifyState), - Category: "MISCELLANEOUS COMMANDS", - Flags: []cli.Flag{ - DataDirFlag, - utils.AncientFlag, - utils.RopstenFlag, - utils.RinkebyFlag, - utils.GoerliFlag, - }, - Description: ` -geth snapshot verify-state -will traverse the whole accounts and storages set based on the specified -snapshot and recalculate the root hash of state for verification. -In other words, this command does the snapshot to trie conversion. -`, - }, - { - Name: "traverse-state", - Usage: "Traverse the EVM state with given root hash for verification", - ArgsUsage: "", - Action: utils.MigrateFlags(traverseState), - Category: "MISCELLANEOUS COMMANDS", - Flags: []cli.Flag{ - DataDirFlag, - utils.AncientFlag, - utils.RopstenFlag, - utils.RinkebyFlag, - utils.GoerliFlag, - }, - Description: ` -geth snapshot traverse-state -will traverse the whole state from the given state root and will abort if any -referenced trie node or contract code is missing. This command can be used for -state integrity verification. The default checking target is the HEAD state. - -It's also usable without snapshot enabled. -`, - }, - { - Name: "traverse-rawstate", - Usage: "Traverse the EVM state with given root hash for verification", - ArgsUsage: "", - Action: utils.MigrateFlags(traverseRawState), - Category: "MISCELLANEOUS COMMANDS", - Flags: []cli.Flag{ - DataDirFlag, - utils.AncientFlag, - utils.RopstenFlag, - utils.RinkebyFlag, - utils.GoerliFlag, - }, - Description: ` -geth snapshot traverse-rawstate -will traverse the whole state from the given root and will abort if any referenced -trie node or contract code is missing. This command can be used for state integrity -verification. The default checking target is the HEAD state. It's basically identical -to traverse-state, but the check granularity is smaller. - -It's also usable without snapshot enabled. -`, - }, - }, - } -) - -func pruneState(ctx *cli.Context) error { - cfg := makeAllConfigs(ctx) - rawDbs := makeDirectDBsProducer(cfg) - gdb := makeGossipStore(rawDbs, cfg) - - if gdb.GetGenesisID() == nil { - return errors.New("failed to open snapshot tree: genesis is not written") - } - - tmpDir := path.Join(cfg.Node.DataDir, "tmp") - _ = os.MkdirAll(tmpDir, 0700) - defer os.RemoveAll(tmpDir) - - genesisBlock := gdb.GetBlock(*gdb.GetGenesisBlockIndex()) - genesisRoot := common.Hash{} - if !ctx.BoolT(PruneGenesisCommand.Name) && genesisBlock != nil { - if gdb.EvmStore().HasStateDB(genesisBlock.Root) { - genesisRoot = common.Hash(genesisBlock.Root) - log.Info("Excluding genesis state from pruning", "root", genesisRoot) - } - } - root := common.Hash(gdb.GetBlockState().FinalizedStateRoot) - var bloom evmpruner.StateBloom - var err error - if ctx.Bool(PruneExactCommand.Name) { - log.Info("Initializing LevelDB storage of in-use-keys") - lset, closer, err := evmpruner.NewLevelDBSet(path.Join(tmpDir, "keys-in-use")) - if err != nil { - log.Error("Failed to create state bloom", "err", err) - return err - } - bloom = lset - defer closer.Close() - } else { - size := ctx.Uint64(utils.BloomFilterSizeFlag.Name) - log.Info("Initializing bloom filter of in-use-keys", "size (MB)", size) - bloom, err = evmpruner.NewProbabilisticSet(size) - if err != nil { - log.Error("Failed to create state bloom", "err", err) - return err - } - } - pruner, err := evmpruner.NewPruner(gdb.EvmStore().EvmDb, genesisRoot, root, tmpDir, bloom) - if err != nil { - log.Error("Failed to open snapshot tree", "err", err) - return err - } - if ctx.NArg() > 1 { - log.Error("Too many arguments given") - return errors.New("too many arguments") - } - var targetRoot common.Hash - if ctx.NArg() == 1 { - targetRoot, err = parseRoot(ctx.Args()[0]) - if err != nil { - log.Error("Failed to resolve state root", "err", err) - return err - } - } - if err = pruner.Prune(targetRoot); err != nil { - log.Error("Failed to prune state", "err", err) - return err - } - return nil -} - -func verifyState(ctx *cli.Context) error { - cfg := makeAllConfigs(ctx) - rawDbs := makeDirectDBsProducer(cfg) - gdb := makeGossipStore(rawDbs, cfg) - - genesis := gdb.GetGenesisID() - if genesis == nil { - return errors.New("failed to open snapshot tree: genesis is not written") - } - - evmStore := gdb.EvmStore() - root := common.Hash(gdb.GetBlockState().FinalizedStateRoot) - - err := evmStore.GenerateEvmSnapshot(root, false, false) - if err != nil { - log.Error("Failed to open snapshot tree", "err", err) - return err - } - if ctx.NArg() > 1 { - log.Error("Too many arguments given") - return errors.New("too many arguments") - } - - if ctx.NArg() == 1 { - root, err = parseRoot(ctx.Args()[0]) - if err != nil { - log.Error("Failed to resolve state root", "err", err) - return err - } - } - if err := evmStore.Snapshots().Verify(root); err != nil { - log.Error("Failed to verfiy state", "root", root, "err", err) - return err - } - log.Info("Verified the state", "root", root) - return nil -} - -// traverseState is a helper function used for pruning verification. -// Basically it just iterates the trie, ensure all nodes and associated -// contract codes are present. -func traverseState(ctx *cli.Context) error { - cfg := makeAllConfigs(ctx) - rawDbs := makeDirectDBsProducer(cfg) - gdb := makeGossipStore(rawDbs, cfg) - - if gdb.GetGenesisID() == nil { - return errors.New("failed to open snapshot tree: genesis is not written") - } - chaindb := gdb.EvmStore().EvmDb - - if ctx.NArg() > 1 { - log.Error("Too many arguments given") - return errors.New("too many arguments") - } - var ( - root common.Hash - err error - ) - if ctx.NArg() == 1 { - root, err = parseRoot(ctx.Args()[0]) - if err != nil { - log.Error("Failed to resolve state root", "err", err) - return err - } - log.Info("Start traversing the state", "root", root) - } else { - root = common.Hash(gdb.GetBlockState().FinalizedStateRoot) - log.Info("Start traversing the state", "root", root, "number", gdb.GetBlockState().LastBlock.Idx) - } - triedb := trie.NewDatabase(chaindb) - t, err := trie.NewSecure(root, triedb) - if err != nil { - log.Error("Failed to open trie", "root", root, "err", err) - return err - } - var ( - accounts int - slots int - codes int - lastReport time.Time - start = time.Now() - ) - accIter := trie.NewIterator(t.NodeIterator(nil)) - for accIter.Next() { - accounts += 1 - var acc state.Account - if err := rlp.DecodeBytes(accIter.Value, &acc); err != nil { - log.Error("Invalid account encountered during traversal", "err", err) - return err - } - if acc.Root != types.EmptyRootHash { - storageTrie, err := trie.NewSecure(acc.Root, triedb) - if err != nil { - log.Error("Failed to open storage trie", "root", acc.Root, "err", err) - return err - } - storageIter := trie.NewIterator(storageTrie.NodeIterator(nil)) - for storageIter.Next() { - slots += 1 - } - if storageIter.Err != nil { - log.Error("Failed to traverse storage trie", "root", acc.Root, "err", storageIter.Err) - return storageIter.Err - } - } - if !bytes.Equal(acc.CodeHash, evmstore.EmptyCode) { - code := rawdb.ReadCode(chaindb, common.BytesToHash(acc.CodeHash)) - if len(code) == 0 { - log.Error("Code is missing", "hash", common.BytesToHash(acc.CodeHash)) - return errors.New("missing code") - } - codes += 1 - } - if time.Since(lastReport) > time.Second*8 { - log.Info("Traversing state", "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) - lastReport = time.Now() - } - } - if accIter.Err != nil { - log.Error("Failed to traverse state trie", "root", root, "err", accIter.Err) - return accIter.Err - } - log.Info("State is complete", "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) - return nil -} - -// traverseRawState is a helper function used for pruning verification. -// Basically it just iterates the trie, ensure all nodes and associated -// contract codes are present. It's basically identical to traverseState -// but it will check each trie node. -func traverseRawState(ctx *cli.Context) error { - cfg := makeAllConfigs(ctx) - rawDbs := makeDirectDBsProducer(cfg) - gdb := makeGossipStore(rawDbs, cfg) - - if gdb.GetGenesisID() == nil { - return errors.New("failed to open snapshot tree: genesis is not written") - } - chaindb := gdb.EvmStore().EvmDb - - if ctx.NArg() > 1 { - log.Error("Too many arguments given") - return errors.New("too many arguments") - } - var ( - root common.Hash - err error - ) - if ctx.NArg() == 1 { - root, err = parseRoot(ctx.Args()[0]) - if err != nil { - log.Error("Failed to resolve state root", "err", err) - return err - } - log.Info("Start traversing the state", "root", root) - } else { - root = common.Hash(gdb.GetBlockState().FinalizedStateRoot) - log.Info("Start traversing the state", "root", root, "number", gdb.GetBlockState().LastBlock.Idx) - } - triedb := trie.NewDatabase(chaindb) - t, err := trie.NewSecure(root, triedb) - if err != nil { - log.Error("Failed to open trie", "root", root, "err", err) - return err - } - var ( - nodes int - accounts int - slots int - codes int - lastReport time.Time - start = time.Now() - ) - accIter := t.NodeIterator(nil) - for accIter.Next(true) { - nodes += 1 - node := accIter.Hash() - - if node != (common.Hash{}) { - // Check the present for non-empty hash node(embedded node doesn't - // have their own hash). - blob := rawdb.ReadTrieNode(chaindb, node) - if len(blob) == 0 { - log.Error("Missing trie node(account)", "hash", node) - return errors.New("missing account") - } - } - // If it's a leaf node, yes we are touching an account, - // dig into the storage trie further. - if accIter.Leaf() { - accounts += 1 - var acc state.Account - if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil { - log.Error("Invalid account encountered during traversal", "err", err) - return errors.New("invalid account") - } - if acc.Root != types.EmptyRootHash { - storageTrie, err := trie.NewSecure(acc.Root, triedb) - if err != nil { - log.Error("Failed to open storage trie", "root", acc.Root, "err", err) - return errors.New("missing storage trie") - } - storageIter := storageTrie.NodeIterator(nil) - for storageIter.Next(true) { - nodes += 1 - node := storageIter.Hash() - - // Check the present for non-empty hash node(embedded node doesn't - // have their own hash). - if node != (common.Hash{}) { - blob := rawdb.ReadTrieNode(chaindb, node) - if len(blob) == 0 { - log.Error("Missing trie node(storage)", "hash", node) - return errors.New("missing storage") - } - } - // Bump the counter if it's leaf node. - if storageIter.Leaf() { - slots += 1 - } - } - if storageIter.Error() != nil { - log.Error("Failed to traverse storage trie", "root", acc.Root, "err", storageIter.Error()) - return storageIter.Error() - } - } - if !bytes.Equal(acc.CodeHash, evmstore.EmptyCode) { - code := rawdb.ReadCode(chaindb, common.BytesToHash(acc.CodeHash)) - if len(code) == 0 { - log.Error("Code is missing", "account", common.BytesToHash(accIter.LeafKey())) - return errors.New("missing code") - } - codes += 1 - } - if time.Since(lastReport) > time.Second*8 { - log.Info("Traversing state", "nodes", nodes, "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) - lastReport = time.Now() - } - } - } - if accIter.Error() != nil { - log.Error("Failed to traverse state trie", "root", root, "err", accIter.Error()) - return accIter.Error() - } - log.Info("State is complete", "nodes", nodes, "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) - return nil -} - -func parseRoot(input string) (common.Hash, error) { - var h common.Hash - if err := h.UnmarshalText([]byte(input)); err != nil { - return h, err - } - return h, nil -} diff --git a/evm/go-x1/cmd/opera/launcher/testdata/dupes/1 b/evm/go-x1/cmd/opera/launcher/testdata/dupes/1 deleted file mode 100644 index a3868ec..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/dupes/1 +++ /dev/null @@ -1 +0,0 @@ -{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} \ No newline at end of file diff --git a/evm/go-x1/cmd/opera/launcher/testdata/dupes/2 b/evm/go-x1/cmd/opera/launcher/testdata/dupes/2 deleted file mode 100644 index a3868ec..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/dupes/2 +++ /dev/null @@ -1 +0,0 @@ -{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} \ No newline at end of file diff --git a/evm/go-x1/cmd/opera/launcher/testdata/dupes/foo b/evm/go-x1/cmd/opera/launcher/testdata/dupes/foo deleted file mode 100644 index c57060a..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/dupes/foo +++ /dev/null @@ -1 +0,0 @@ -{"address":"7ef5a6135f1fd6a02593eedc869c6d41d934aef8","crypto":{"cipher":"aes-128-ctr","ciphertext":"1d0839166e7a15b9c1333fc865d69858b22df26815ccf601b28219b6192974e1","cipherparams":{"iv":"8df6caa7ff1b00c4e871f002cb7921ed"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"e5e6ef3f4ea695f496b643ebd3f75c0aa58ef4070e90c80c5d3fb0241bf1595c"},"mac":"6d16dfde774845e4585357f24bce530528bc69f4f84e1e22880d34fa45c273e5"},"id":"950077c7-71e3-4c44-a4a1-143919141ed4","version":3} \ No newline at end of file diff --git a/evm/go-x1/cmd/opera/launcher/testdata/empty.js b/evm/go-x1/cmd/opera/launcher/testdata/empty.js deleted file mode 100644 index 8b13789..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/empty.js +++ /dev/null @@ -1 +0,0 @@ - diff --git a/evm/go-x1/cmd/opera/launcher/testdata/guswallet.json b/evm/go-x1/cmd/opera/launcher/testdata/guswallet.json deleted file mode 100644 index e8ea4f3..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/guswallet.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "encseed": "26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba", - "ethaddr": "d4584b5f6229b7be90727b0fc8c6b91bb427821f", - "email": "gustav.simonsson@gmail.com", - "btcaddr": "1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx" -} diff --git a/evm/go-x1/cmd/opera/launcher/testdata/keystore/.hiddenfile b/evm/go-x1/cmd/opera/launcher/testdata/keystore/.hiddenfile deleted file mode 100644 index d91facc..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/keystore/.hiddenfile +++ /dev/null @@ -1 +0,0 @@ -{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} diff --git a/evm/go-x1/cmd/opera/launcher/testdata/keystore/README b/evm/go-x1/cmd/opera/launcher/testdata/keystore/README deleted file mode 100644 index a5a86f9..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/keystore/README +++ /dev/null @@ -1,21 +0,0 @@ -This directory contains accounts for testing. -The passphrase that unlocks them is "foobar". - -The "good" key files which are supposed to be loadable are: - -- File: UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 - Address: 0x7ef5a6135f1fd6a02593eedc869c6d41d934aef8 -- File: aaa - Address: 0xf466859ead1932d743d622cb74fc058882e8648a -- File: zzz - Address: 0x289d485d9771714cce91d3393d764e1311907acc - -The other files (including this README) are broken in various ways -and should not be picked up by package accounts: - -- File: no-address (missing address field, otherwise same as "aaa") -- File: garbage (file with random data) -- File: empty (file with no content) -- File: swapfile~ (should be skipped) -- File: .hiddenfile (should be skipped) -- File: foo/... (should be skipped because it is a directory) diff --git a/evm/go-x1/cmd/opera/launcher/testdata/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 b/evm/go-x1/cmd/opera/launcher/testdata/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 deleted file mode 100644 index c57060a..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 +++ /dev/null @@ -1 +0,0 @@ -{"address":"7ef5a6135f1fd6a02593eedc869c6d41d934aef8","crypto":{"cipher":"aes-128-ctr","ciphertext":"1d0839166e7a15b9c1333fc865d69858b22df26815ccf601b28219b6192974e1","cipherparams":{"iv":"8df6caa7ff1b00c4e871f002cb7921ed"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"e5e6ef3f4ea695f496b643ebd3f75c0aa58ef4070e90c80c5d3fb0241bf1595c"},"mac":"6d16dfde774845e4585357f24bce530528bc69f4f84e1e22880d34fa45c273e5"},"id":"950077c7-71e3-4c44-a4a1-143919141ed4","version":3} \ No newline at end of file diff --git a/evm/go-x1/cmd/opera/launcher/testdata/keystore/aaa b/evm/go-x1/cmd/opera/launcher/testdata/keystore/aaa deleted file mode 100644 index a3868ec..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/keystore/aaa +++ /dev/null @@ -1 +0,0 @@ -{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} \ No newline at end of file diff --git a/evm/go-x1/cmd/opera/launcher/testdata/keystore/empty b/evm/go-x1/cmd/opera/launcher/testdata/keystore/empty deleted file mode 100644 index e69de29..0000000 diff --git a/evm/go-x1/cmd/opera/launcher/testdata/keystore/foo/fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e b/evm/go-x1/cmd/opera/launcher/testdata/keystore/foo/fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e deleted file mode 100644 index 309841e..0000000 --- a/evm/go-x1/cmd/opera/launcher/testdata/keystore/foo/fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e +++ /dev/null @@ -1 +0,0 @@ -{"address":"fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e","crypto":{"cipher":"aes-128-ctr","ciphertext":"8124d5134aa4a927c79fd852989e4b5419397566f04b0936a1eb1d168c7c68a5","cipherparams":{"iv":"e2febe17176414dd2cda28287947eb2f"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"44b415ede89f3bdd6830390a21b78965f571b347a589d1d943029f016c5e8bd5"},"mac":"5e149ff25bfd9dd45746a84bb2bcd2f015f2cbca2b6d25c5de8c29617f71fe5b"},"id":"d6ac5452-2b2c-4d3c-ad80-4bf0327d971c","version":3} \ No newline at end of file diff --git a/evm/go-x1/cmd/opera/launcher/testdata/keystore/garbage b/evm/go-x1/cmd/opera/launcher/testdata/keystore/garbage deleted file mode 100644 index ff45091e714078dd7d3b4ea95964452e33a895f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 300 zcmV+{0n`3r1xkOa0KiH=0-y31ays31&4D+~b{#6-MH z)8?iosg+26q81!5ujp29iM}4_d}^;*-$8$htAbEpk(KDl*$;NvD$v8GZL@TRuT#)+ zq*|PXNljY5_xwCfoMayTjJ(vY;=t!uVJT5-Fn0O7W{#e;Ho?+NsQQi=!GV>j#9U#& zAbp7L1M-8N-V+7}EDxG9CNuhKbj?($B?=E1a1Xi%v;bYvR+C$EjApbg!W^>zB$Cd( z+NKd!El}@p)NJLnQ}B=D#e5uCh87_~lKd2z=idP7$. - -// Contains the geth command usage template and generator. - -package launcher - -import ( - "io" - "sort" - - "github.com/ethereum/go-ethereum/cmd/utils" - cli "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/debug" - "github.com/Fantom-foundation/go-opera/flags" -) - -// AppHelpFlagGroups is the application flags, grouped by functionality. -var AppHelpFlagGroups = calcAppHelpFlagGroups() - -func calcAppHelpFlagGroups() []flags.FlagGroup { - overrideFlags() - overrideParams() - - initFlags() - return []flags.FlagGroup{ - { - Name: "X1", - Flags: operaFlags, - }, - { - Name: "TRANSACTION POOL", - Flags: txpoolFlags, - }, - { - Name: "PERFORMANCE TUNING", - Flags: performanceFlags, - }, - { - Name: "ACCOUNT", - Flags: accountFlags, - }, - { - Name: "API", - Flags: rpcFlags, - }, - { - Name: "CONSOLE", - Flags: consoleFlags, - }, - { - Name: "NETWORKING", - Flags: networkingFlags, - }, - { - Name: "GAS PRICE ORACLE", - Flags: gpoFlags, - }, - { - Name: "METRICS AND STATS", - Flags: metricsFlags, - }, - { - Name: "TESTING", - Flags: testFlags, - }, - { - Name: "LOGGING AND DEBUGGING", - Flags: debug.Flags, - }, - { - Name: "ALIASED (deprecated)", - Flags: legacyRpcFlags, - }, - { - Name: "MISC", - Flags: []cli.Flag{ - cli.HelpFlag, - }, - }, - } -} - -func init() { - // Override the default app help template - cli.AppHelpTemplate = flags.AppHelpTemplate - - // Override the default app help printer, but only for the global app help - originalHelpPrinter := cli.HelpPrinter - cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { - if tmpl == flags.AppHelpTemplate { - // Iterate over all the flags and add any uncategorized ones - categorized := make(map[string]struct{}) - for _, group := range AppHelpFlagGroups { - for _, flag := range group.Flags { - categorized[flag.String()] = struct{}{} - } - } - deprecated := make(map[string]struct{}) - for _, flag := range utils.DeprecatedFlags { - deprecated[flag.String()] = struct{}{} - } - // Only add uncategorized flags if they are not deprecated - var uncategorized []cli.Flag - for _, flag := range data.(*cli.App).Flags { - if _, ok := categorized[flag.String()]; !ok { - if _, ok := deprecated[flag.String()]; !ok { - uncategorized = append(uncategorized, flag) - } - } - } - if len(uncategorized) > 0 { - // Append all ungategorized options to the misc group - miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags) - AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...) - - // Make sure they are removed afterwards - defer func() { - AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs] - }() - } - // Render out custom usage screen - originalHelpPrinter(w, tmpl, flags.HelpData{App: data, FlagGroups: AppHelpFlagGroups}) - } else if tmpl == flags.CommandHelpTemplate { - // Iterate over all command specific flags and categorize them - categorized := make(map[string][]cli.Flag) - for _, flag := range data.(cli.Command).Flags { - if _, ok := categorized[flag.String()]; !ok { - categorized[flags.FlagCategory(flag, AppHelpFlagGroups)] = append(categorized[flags.FlagCategory(flag, AppHelpFlagGroups)], flag) - } - } - - // sort to get a stable ordering - sorted := make([]flags.FlagGroup, 0, len(categorized)) - for cat, flgs := range categorized { - sorted = append(sorted, flags.FlagGroup{Name: cat, Flags: flgs}) - } - sort.Sort(flags.ByCategory(sorted)) - - // add sorted array to data and render with default printer - originalHelpPrinter(w, tmpl, map[string]interface{}{ - "cmd": data, - "categorizedFlags": sorted, - }) - } else { - originalHelpPrinter(w, tmpl, data) - } - } -} diff --git a/evm/go-x1/cmd/opera/launcher/validator.go b/evm/go-x1/cmd/opera/launcher/validator.go deleted file mode 100644 index 1f128c6..0000000 --- a/evm/go-x1/cmd/opera/launcher/validator.go +++ /dev/null @@ -1,67 +0,0 @@ -package launcher - -import ( - "github.com/pkg/errors" - cli "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" - "github.com/Fantom-foundation/go-opera/inter/validatorpk" -) - -var validatorIDFlag = cli.UintFlag{ - Name: "validator.id", - Usage: "ID of a validator to create events from", - Value: 0, -} - -var validatorPubkeyFlag = cli.StringFlag{ - Name: "validator.pubkey", - Usage: "Public key of a validator to create events from", - Value: "", -} - -var validatorPasswordFlag = cli.StringFlag{ - Name: "validator.password", - Usage: "Password to unlock validator private key", - Value: "", -} - -// setValidatorID retrieves the validator ID either from the directly specified -// command line flags or from the keystore if CLI indexed. -func setValidator(ctx *cli.Context, cfg *emitter.Config) error { - // Extract the current validator address, new flag overriding legacy one - if ctx.GlobalIsSet(FakeNetFlag.Name) { - id, num, err := parseFakeGen(ctx.GlobalString(FakeNetFlag.Name)) - if err != nil { - return err - } - - if ctx.GlobalIsSet(validatorIDFlag.Name) && id != 0 { - return errors.New("specified validator ID with both --fakenet and --validator.id") - } - - cfg.Validator.ID = id - validators := makefakegenesis.GetFakeValidators(num) - cfg.Validator.PubKey = validators.Map()[cfg.Validator.ID].PubKey - } - - if ctx.GlobalIsSet(validatorIDFlag.Name) { - cfg.Validator.ID = idx.ValidatorID(ctx.GlobalInt(validatorIDFlag.Name)) - } - - if ctx.GlobalIsSet(validatorPubkeyFlag.Name) { - pk, err := validatorpk.FromString(ctx.GlobalString(validatorPubkeyFlag.Name)) - if err != nil { - return err - } - cfg.Validator.PubKey = pk - } - - if cfg.Validator.ID != 0 && cfg.Validator.PubKey.Empty() { - return errors.New("validator public key is not set") - } - return nil -} diff --git a/evm/go-x1/cmd/opera/launcher/validatorcmd.go b/evm/go-x1/cmd/opera/launcher/validatorcmd.go deleted file mode 100644 index 7c2fbe1..0000000 --- a/evm/go-x1/cmd/opera/launcher/validatorcmd.go +++ /dev/null @@ -1,160 +0,0 @@ -package launcher - -import ( - "crypto/ecdsa" - "crypto/rand" - "fmt" - "path" - "strings" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/valkeystore" - "github.com/Fantom-foundation/go-opera/valkeystore/encryption" -) - -var ( - validatorCommand = cli.Command{ - Name: "validator", - Usage: "Manage validators", - Category: "VALIDATOR COMMANDS", - Description: ` - -Create a new validator private key. - -It supports interactive mode, when you are prompted for password as well as -non-interactive mode where passwords are supplied via a given password file. -Non-interactive mode is only meant for scripted use on test networks or known -safe environments. - -Make sure you remember the password you gave when creating a new validator key. -Without it you are not able to unlock your validator key. - -Note that exporting your key in unencrypted format is NOT supported. - -Keys are stored under /keystore/validator. -It is safe to transfer the entire directory or the individual keys therein -between Opera nodes by simply copying. - -Make sure you backup your keys regularly.`, - Subcommands: []cli.Command{ - { - Name: "new", - Usage: "Create a new validator key", - Action: utils.MigrateFlags(validatorKeyCreate), - Flags: []cli.Flag{ - DataDirFlag, - utils.KeyStoreDirFlag, - utils.PasswordFileFlag, - }, - Description: ` - opera validator new - -Creates a new validator private key and prints the public key. - -The key is saved in encrypted format, you are prompted for a passphrase. - -You must remember this passphrase to unlock your key in the future. - -For non-interactive use the passphrase can be specified with the --validator.password flag: - -Note, this is meant to be used for testing only, it is a bad idea to save your -password to file or expose in any other way. -`, - }, - { - Name: "convert", - Usage: "Convert an account key to a validator key", - Action: utils.MigrateFlags(validatorKeyConvert), - Flags: []cli.Flag{ - DataDirFlag, - utils.KeyStoreDirFlag, - }, - ArgsUsage: " ", - Description: ` - opera validator convert - -Converts an account private key to a validator private key and saves in the validator keystore. -`, - }, - }, - } -) - -// validatorKeyCreate creates a new validator key into the keystore defined by the CLI flags. -func validatorKeyCreate(ctx *cli.Context) error { - cfg := makeAllConfigs(ctx) - utils.SetNodeConfig(ctx, &cfg.Node) - - password := getPassPhrase("Your new validator key is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) - - privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader) - if err != nil { - utils.Fatalf("Failed to create account: %v", err) - } - privateKey := crypto.FromECDSA(privateKeyECDSA) - publicKey := validatorpk.PubKey{ - Raw: crypto.FromECDSAPub(&privateKeyECDSA.PublicKey), - Type: validatorpk.Types.Secp256k1, - } - - valKeystore := valkeystore.NewDefaultFileRawKeystore(path.Join(getValKeystoreDir(cfg.Node), "validator")) - err = valKeystore.Add(publicKey, privateKey, password) - if err != nil { - utils.Fatalf("Failed to create account: %v", err) - } - - // Sanity check - _, err = valKeystore.Get(publicKey, password) - if err != nil { - utils.Fatalf("Failed to decrypt the account: %v", err) - } - - fmt.Printf("\nYour new key was generated\n\n") - fmt.Printf("Public key: %s\n", publicKey.String()) - fmt.Printf("Path of the secret key file: %s\n\n", valKeystore.PathOf(publicKey)) - fmt.Printf("- You can share your public key with anyone. Others need it to validate messages from you.\n") - fmt.Printf("- You must NEVER share the secret key with anyone! The key controls access to your validator!\n") - fmt.Printf("- You must BACKUP your key file! Without the key, it's impossible to operate the validator!\n") - fmt.Printf("- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!\n\n") - return nil -} - -// validatorKeyConvert converts account key to validator key. -func validatorKeyConvert(ctx *cli.Context) error { - if len(ctx.Args()) < 2 { - utils.Fatalf("This command requires 2 arguments.") - } - cfg := makeAllConfigs(ctx) - utils.SetNodeConfig(ctx, &cfg.Node) - - _, _, keydir, _ := cfg.Node.AccountConfig() - - pubkeyStr := ctx.Args().Get(1) - pubkey, err := validatorpk.FromString(pubkeyStr) - if err != nil { - utils.Fatalf("Failed to decode the validator pubkey: %v", err) - } - - var acckeypath string - if strings.HasPrefix(ctx.Args().First(), "0x") { - acckeypath, err = FindAccountKeypath(common.HexToAddress(ctx.Args().First()), keydir) - if err != nil { - utils.Fatalf("Failed to find the account: %v", err) - } - } else { - acckeypath = ctx.Args().First() - } - - valkeypath := path.Join(keydir, "validator", common.Bytes2Hex(pubkey.Bytes())) - err = encryption.MigrateAccountToValidatorKey(acckeypath, valkeypath, pubkey) - if err != nil { - utils.Fatalf("Failed to migrate the account key: %v", err) - } - fmt.Println("\nYour key was converted and saved to " + valkeypath) - return nil -} diff --git a/evm/go-x1/cmd/opera/launcher/valkeystore.go b/evm/go-x1/cmd/opera/launcher/valkeystore.go deleted file mode 100644 index e2b185a..0000000 --- a/evm/go-x1/cmd/opera/launcher/valkeystore.go +++ /dev/null @@ -1,76 +0,0 @@ -package launcher - -import ( - "crypto/ecdsa" - "fmt" - "io/ioutil" - "strings" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - cli "gopkg.in/urfave/cli.v1" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/valkeystore" -) - -func addFakeValidatorKey(ctx *cli.Context, key *ecdsa.PrivateKey, pubkey validatorpk.PubKey, valKeystore valkeystore.RawKeystoreI) { - // add fake validator key - if key != nil && !valKeystore.Has(pubkey) { - err := valKeystore.Add(pubkey, crypto.FromECDSA(key), validatorpk.FakePassword) - if err != nil { - utils.Fatalf("Failed to add fake validator key: %v", err) - } - } -} - -func getValKeystoreDir(cfg node.Config) string { - _, _, keydir, err := cfg.AccountConfig() - if err != nil { - utils.Fatalf("Failed to setup account config: %v", err) - } - return keydir -} - -// makeValidatorPasswordList reads password lines from the file specified by the global --validator.password flag. -func makeValidatorPasswordList(ctx *cli.Context) []string { - if path := ctx.GlobalString(validatorPasswordFlag.Name); path != "" { - text, err := ioutil.ReadFile(path) - if err != nil { - utils.Fatalf("Failed to read password file: %v", err) - } - lines := strings.Split(string(text), "\n") - // Sanitise DOS line endings. - for i := range lines { - lines[i] = strings.TrimRight(lines[i], "\r") - } - return lines - } - if ctx.GlobalIsSet(FakeNetFlag.Name) { - return []string{validatorpk.FakePassword} - } - return nil -} - -func unlockValidatorKey(ctx *cli.Context, pubKey validatorpk.PubKey, valKeystore valkeystore.KeystoreI) error { - if !valKeystore.Has(pubKey) { - return valkeystore.ErrNotFound - } - var err error - for trials := 0; trials < 3; trials++ { - prompt := fmt.Sprintf("Unlocking validator key %s | Attempt %d/%d", pubKey.String(), trials+1, 3) - password := getPassPhrase(prompt, false, 0, makeValidatorPasswordList(ctx)) - err = valKeystore.Unlock(pubKey, password) - if err == nil { - log.Info("Unlocked validator key", "pubkey", pubKey.String()) - return nil - } - if err.Error() != "could not decrypt key with given password" { - return err - } - } - // All trials expended to unlock account, bail out - return err -} diff --git a/evm/go-x1/cmd/opera/launcher/x1testnet.go b/evm/go-x1/cmd/opera/launcher/x1testnet.go deleted file mode 100644 index 5fb9cd6..0000000 --- a/evm/go-x1/cmd/opera/launcher/x1testnet.go +++ /dev/null @@ -1,17 +0,0 @@ -package launcher - -import ( - "crypto/ecdsa" - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" - cli "gopkg.in/urfave/cli.v1" -) - -// X1TestnetFlag enables special testnet, where validators are automatically created -var X1TestnetFlag = cli.BoolFlag{ - Name: "x1-testnet", - Usage: "Generates X1 testnet genesis and starts the chain", -} - -func getX1ValidatorKey(ctx *cli.Context) *ecdsa.PrivateKey { - return makefakegenesis.FakeKey(1) -} diff --git a/evm/go-x1/cmd/opera/main.go b/evm/go-x1/cmd/opera/main.go deleted file mode 100644 index 5c29d15..0000000 --- a/evm/go-x1/cmd/opera/main.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/Fantom-foundation/go-opera/cmd/opera/launcher" -) - -func main() { - if err := launcher.Launch(os.Args); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} diff --git a/evm/go-x1/debug/api.go b/evm/go-x1/debug/api.go deleted file mode 100644 index efd8626..0000000 --- a/evm/go-x1/debug/api.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package debug interfaces Go runtime debugging facilities. -// This package is mostly glue code making these facilities available -// through the CLI and RPC subsystem. If you want to use them from Go code, -// use package runtime instead. -package debug - -import ( - "bytes" - "errors" - "io" - "os" - "os/user" - "path/filepath" - "runtime" - "runtime/debug" - "runtime/pprof" - "strings" - "sync" - "time" - - "github.com/ethereum/go-ethereum/log" -) - -// Handler is the global debugging handler. -var Handler = new(HandlerT) - -// HandlerT implements the debugging API. -// Do not create values of this type, use the one -// in the Handler variable instead. -type HandlerT struct { - mu sync.Mutex - cpuW io.WriteCloser - cpuFile string - traceW io.WriteCloser - traceFile string -} - -// Verbosity sets the log verbosity ceiling. The verbosity of individual packages -// and source files can be raised using Vmodule. -func (*HandlerT) Verbosity(level int) { - glogger.Verbosity(log.Lvl(level)) -} - -// Vmodule sets the log verbosity pattern. See package log for details on the -// pattern syntax. -func (*HandlerT) Vmodule(pattern string) error { - return glogger.Vmodule(pattern) -} - -// BacktraceAt sets the log backtrace location. See package log for details on -// the pattern syntax. -func (*HandlerT) BacktraceAt(location string) error { - return glogger.BacktraceAt(location) -} - -// MemStats returns detailed runtime memory statistics. -func (*HandlerT) MemStats() *runtime.MemStats { - s := new(runtime.MemStats) - runtime.ReadMemStats(s) - return s -} - -// GcStats returns GC statistics. -func (*HandlerT) GcStats() *debug.GCStats { - s := new(debug.GCStats) - debug.ReadGCStats(s) - return s -} - -// CpuProfile turns on CPU profiling for nsec seconds and writes -// profile data to file. -func (h *HandlerT) CpuProfile(file string, nsec uint) error { - if err := h.StartCPUProfile(file); err != nil { - return err - } - time.Sleep(time.Duration(nsec) * time.Second) - h.StopCPUProfile() - return nil -} - -// StartCPUProfile turns on CPU profiling, writing to the given file. -func (h *HandlerT) StartCPUProfile(file string) error { - h.mu.Lock() - defer h.mu.Unlock() - if h.cpuW != nil { - return errors.New("CPU profiling already in progress") - } - f, err := os.Create(expandHome(file)) - if err != nil { - return err - } - if err := pprof.StartCPUProfile(f); err != nil { - f.Close() - return err - } - h.cpuW = f - h.cpuFile = file - log.Info("CPU profiling started", "dump", h.cpuFile) - return nil -} - -// StopCPUProfile stops an ongoing CPU profile. -func (h *HandlerT) StopCPUProfile() error { - h.mu.Lock() - defer h.mu.Unlock() - pprof.StopCPUProfile() - if h.cpuW == nil { - return errors.New("CPU profiling not in progress") - } - log.Info("Done writing CPU profile", "dump", h.cpuFile) - h.cpuW.Close() - h.cpuW = nil - h.cpuFile = "" - return nil -} - -// GoTrace turns on tracing for nsec seconds and writes -// trace data to file. -func (h *HandlerT) GoTrace(file string, nsec uint) error { - if err := h.StartGoTrace(file); err != nil { - return err - } - time.Sleep(time.Duration(nsec) * time.Second) - h.StopGoTrace() - return nil -} - -// BlockProfile turns on goroutine profiling for nsec seconds and writes profile data to -// file. It uses a profile rate of 1 for most accurate information. If a different rate is -// desired, set the rate and write the profile manually. -func (*HandlerT) BlockProfile(file string, nsec uint) error { - runtime.SetBlockProfileRate(1) - time.Sleep(time.Duration(nsec) * time.Second) - defer runtime.SetBlockProfileRate(0) - return writeProfile("block", file) -} - -// SetBlockProfileRate sets the rate of goroutine block profile data collection. -// rate 0 disables block profiling. -func (*HandlerT) SetBlockProfileRate(rate int) { - runtime.SetBlockProfileRate(rate) -} - -// WriteBlockProfile writes a goroutine blocking profile to the given file. -func (*HandlerT) WriteBlockProfile(file string) error { - return writeProfile("block", file) -} - -// MutexProfile turns on mutex profiling for nsec seconds and writes profile data to file. -// It uses a profile rate of 1 for most accurate information. If a different rate is -// desired, set the rate and write the profile manually. -func (*HandlerT) MutexProfile(file string, nsec uint) error { - runtime.SetMutexProfileFraction(1) - time.Sleep(time.Duration(nsec) * time.Second) - defer runtime.SetMutexProfileFraction(0) - return writeProfile("mutex", file) -} - -// SetMutexProfileFraction sets the rate of mutex profiling. -func (*HandlerT) SetMutexProfileFraction(rate int) { - runtime.SetMutexProfileFraction(rate) -} - -// WriteMutexProfile writes a goroutine blocking profile to the given file. -func (*HandlerT) WriteMutexProfile(file string) error { - return writeProfile("mutex", file) -} - -// WriteMemProfile writes an allocation profile to the given file. -// Note that the profiling rate cannot be set through the API, -// it must be set on the command line. -func (*HandlerT) WriteMemProfile(file string) error { - return writeProfile("heap", file) -} - -// Stacks returns a printed representation of the stacks of all goroutines. -func (*HandlerT) Stacks() string { - buf := new(bytes.Buffer) - pprof.Lookup("goroutine").WriteTo(buf, 2) - return buf.String() -} - -// FreeOSMemory forces a garbage collection. -func (*HandlerT) FreeOSMemory() { - debug.FreeOSMemory() -} - -// SetGCPercent sets the garbage collection target percentage. It returns the previous -// setting. A negative value disables GC. -func (*HandlerT) SetGCPercent(v int) int { - return debug.SetGCPercent(v) -} - -func writeProfile(name, file string) error { - p := pprof.Lookup(name) - log.Info("Writing profile records", "count", p.Count(), "type", name, "dump", file) - f, err := os.Create(expandHome(file)) - if err != nil { - return err - } - defer f.Close() - return p.WriteTo(f, 0) -} - -// expands home directory in file paths. -// ~someuser/tmp will not be expanded. -func expandHome(p string) string { - if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") { - home := os.Getenv("HOME") - if home == "" { - if usr, err := user.Current(); err == nil { - home = usr.HomeDir - } - } - if home != "" { - p = home + p[1:] - } - } - return filepath.Clean(p) -} diff --git a/evm/go-x1/debug/flags.go b/evm/go-x1/debug/flags.go deleted file mode 100644 index 126ee09..0000000 --- a/evm/go-x1/debug/flags.go +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package debug - -import ( - "fmt" - "io" - "net/http" - _ "net/http/pprof" - "os" - "runtime" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/metrics/exp" - "github.com/fjl/memsize/memsizeui" - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" - "gopkg.in/urfave/cli.v1" -) - -var Memsize memsizeui.Handler - -var ( - verbosityFlag = cli.IntFlag{ - Name: "verbosity", - Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail", - Value: 3, - } - vmoduleFlag = cli.StringFlag{ - Name: "vmodule", - Usage: "Per-module verbosity: comma-separated list of = (e.g. eth/*=5,p2p=4)", - Value: "", - } - logjsonFlag = cli.BoolFlag{ - Name: "log.json", - Usage: "Format logs with JSON", - } - backtraceAtFlag = cli.StringFlag{ - Name: "log.backtrace", - Usage: "Request a stack trace at a specific logging statement (e.g. \"block.go:271\")", - Value: "", - } - debugFlag = cli.BoolFlag{ - Name: "log.debug", - Usage: "Prepends log messages with call-site location (file and line number)", - } - pprofFlag = cli.BoolFlag{ - Name: "pprof", - Usage: "Enable the pprof HTTP server", - } - pprofPortFlag = cli.IntFlag{ - Name: "pprof.port", - Usage: "pprof HTTP server listening port", - Value: 6060, - } - pprofAddrFlag = cli.StringFlag{ - Name: "pprof.addr", - Usage: "pprof HTTP server listening interface", - Value: "127.0.0.1", - } - memprofilerateFlag = cli.IntFlag{ - Name: "pprof.memprofilerate", - Usage: "Turn on memory profiling with the given rate", - Value: runtime.MemProfileRate, - } - blockprofilerateFlag = cli.IntFlag{ - Name: "pprof.blockprofilerate", - Usage: "Turn on block profiling with the given rate", - } - cpuprofileFlag = cli.StringFlag{ - Name: "pprof.cpuprofile", - Usage: "Write CPU profile to the given file", - } - traceFlag = cli.StringFlag{ - Name: "trace", - Usage: "Write execution trace to the given file", - } - // (Deprecated April 2020) - legacyPprofPortFlag = cli.IntFlag{ - Name: "pprofport", - Usage: "pprof HTTP server listening port (deprecated, use --pprof.port)", - Value: 6060, - } - legacyPprofAddrFlag = cli.StringFlag{ - Name: "pprofaddr", - Usage: "pprof HTTP server listening interface (deprecated, use --pprof.addr)", - Value: "127.0.0.1", - } - legacyMemprofilerateFlag = cli.IntFlag{ - Name: "memprofilerate", - Usage: "Turn on memory profiling with the given rate (deprecated, use --pprof.memprofilerate)", - Value: runtime.MemProfileRate, - } - legacyBlockprofilerateFlag = cli.IntFlag{ - Name: "blockprofilerate", - Usage: "Turn on block profiling with the given rate (deprecated, use --pprof.blockprofilerate)", - } - legacyCpuprofileFlag = cli.StringFlag{ - Name: "cpuprofile", - Usage: "Write CPU profile to the given file (deprecated, use --pprof.cpuprofile)", - } - legacyBacktraceAtFlag = cli.StringFlag{ - Name: "backtrace", - Usage: "Request a stack trace at a specific logging statement (e.g. \"block.go:271\") (deprecated, use --log.backtrace)", - Value: "", - } - legacyDebugFlag = cli.BoolFlag{ - Name: "debug", - Usage: "Prepends log messages with call-site location (file and line number) (deprecated, use --log.debug)", - } -) - -// Flags holds all command-line flags required for debugging. -var Flags = []cli.Flag{ - verbosityFlag, - vmoduleFlag, - logjsonFlag, - backtraceAtFlag, - debugFlag, - pprofFlag, - pprofAddrFlag, - pprofPortFlag, - memprofilerateFlag, - blockprofilerateFlag, - cpuprofileFlag, - traceFlag, -} - -// This is the list of deprecated debugging flags. -var DeprecatedFlags = []cli.Flag{ - legacyPprofPortFlag, - legacyPprofAddrFlag, - legacyMemprofilerateFlag, - legacyBlockprofilerateFlag, - legacyCpuprofileFlag, - legacyBacktraceAtFlag, - legacyDebugFlag, -} - -var glogger *log.GlogHandler - -func init() { - glogger = log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) - glogger.Verbosity(log.LvlInfo) - log.Root().SetHandler(glogger) -} - -// Setup initializes profiling and logging based on the CLI flags. -// It should be called as early as possible in the program. -func Setup(ctx *cli.Context) error { - var ostream log.Handler - output := io.Writer(os.Stderr) - if ctx.GlobalBool(logjsonFlag.Name) { - ostream = log.StreamHandler(output, log.JSONFormat()) - } else { - usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb" - if usecolor { - output = colorable.NewColorableStderr() - } - ostream = log.StreamHandler(output, log.TerminalFormat(usecolor)) - } - glogger.SetHandler(ostream) - - // logging - verbosity := ctx.GlobalInt(verbosityFlag.Name) - glogger.Verbosity(log.Lvl(verbosity)) - vmodule := ctx.GlobalString(vmoduleFlag.Name) - glogger.Vmodule(vmodule) - - debug := ctx.GlobalBool(debugFlag.Name) - if ctx.GlobalIsSet(legacyDebugFlag.Name) { - debug = ctx.GlobalBool(legacyDebugFlag.Name) - log.Warn("The flag --debug is deprecated and will be removed in the future, please use --log.debug") - } - if ctx.GlobalIsSet(debugFlag.Name) { - debug = ctx.GlobalBool(debugFlag.Name) - } - log.PrintOrigins(debug) - - backtrace := ctx.GlobalString(backtraceAtFlag.Name) - if b := ctx.GlobalString(legacyBacktraceAtFlag.Name); b != "" { - backtrace = b - log.Warn("The flag --backtrace is deprecated and will be removed in the future, please use --log.backtrace") - } - if b := ctx.GlobalString(backtraceAtFlag.Name); b != "" { - backtrace = b - } - glogger.BacktraceAt(backtrace) - - log.Root().SetHandler(glogger) - - // profiling, tracing - runtime.MemProfileRate = memprofilerateFlag.Value - if ctx.GlobalIsSet(legacyMemprofilerateFlag.Name) { - runtime.MemProfileRate = ctx.GlobalInt(legacyMemprofilerateFlag.Name) - log.Warn("The flag --memprofilerate is deprecated and will be removed in the future, please use --pprof.memprofilerate") - } - if ctx.GlobalIsSet(memprofilerateFlag.Name) { - runtime.MemProfileRate = ctx.GlobalInt(memprofilerateFlag.Name) - } - - blockProfileRate := blockprofilerateFlag.Value - if ctx.GlobalIsSet(legacyBlockprofilerateFlag.Name) { - blockProfileRate = ctx.GlobalInt(legacyBlockprofilerateFlag.Name) - log.Warn("The flag --blockprofilerate is deprecated and will be removed in the future, please use --pprof.blockprofilerate") - } - if ctx.GlobalIsSet(blockprofilerateFlag.Name) { - blockProfileRate = ctx.GlobalInt(blockprofilerateFlag.Name) - } - Handler.SetBlockProfileRate(blockProfileRate) - - if traceFile := ctx.GlobalString(traceFlag.Name); traceFile != "" { - if err := Handler.StartGoTrace(traceFile); err != nil { - return err - } - } - - if cpuFile := ctx.GlobalString(cpuprofileFlag.Name); cpuFile != "" { - if err := Handler.StartCPUProfile(cpuFile); err != nil { - return err - } - } - - // pprof server - if ctx.GlobalBool(pprofFlag.Name) { - listenHost := ctx.GlobalString(pprofAddrFlag.Name) - - port := ctx.GlobalInt(pprofPortFlag.Name) - - address := fmt.Sprintf("%s:%d", listenHost, port) - // This context value ("metrics.addr") represents the utils.MetricsHTTPFlag.Name. - // It cannot be imported because it will cause a cyclical dependency. - StartPProf(address, !ctx.GlobalIsSet("metrics.addr")) - } - return nil -} - -func StartPProf(address string, withMetrics bool) { - // Hook go-metrics into expvar on any /debug/metrics request, load all vars - // from the registry into expvar, and execute regular expvar handler. - if withMetrics { - exp.Exp(metrics.DefaultRegistry) - } - http.Handle("/memsize/", http.StripPrefix("/memsize", &Memsize)) - log.Info("Starting pprof server", "addr", fmt.Sprintf("http://%s/debug/pprof", address)) - go func() { - if err := http.ListenAndServe(address, nil); err != nil { - log.Error("Failure in running pprof server", "err", err) - } - }() -} - -// Exit stops all running profiles, flushing their output to the -// respective file. -func Exit() { - Handler.StopCPUProfile() - Handler.StopGoTrace() -} diff --git a/evm/go-x1/debug/loudpanic.go b/evm/go-x1/debug/loudpanic.go deleted file mode 100644 index 86e6bc8..0000000 --- a/evm/go-x1/debug/loudpanic.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build go1.6 -// +build go1.6 - -package debug - -import "runtime/debug" - -// LoudPanic panics in a way that gets all goroutine stacks printed on stderr. -func LoudPanic(x interface{}) { - debug.SetTraceback("all") - panic(x) -} diff --git a/evm/go-x1/debug/loudpanic_fallback.go b/evm/go-x1/debug/loudpanic_fallback.go deleted file mode 100644 index 377490e..0000000 --- a/evm/go-x1/debug/loudpanic_fallback.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build !go1.6 -// +build !go1.6 - -package debug - -// LoudPanic panics in a way that gets all goroutine stacks printed on stderr. -func LoudPanic(x interface{}) { - panic(x) -} diff --git a/evm/go-x1/debug/trace.go b/evm/go-x1/debug/trace.go deleted file mode 100644 index a273e4a..0000000 --- a/evm/go-x1/debug/trace.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build go1.5 -// +build go1.5 - -package debug - -import ( - "errors" - "os" - "runtime/trace" - - "github.com/ethereum/go-ethereum/log" -) - -// StartGoTrace turns on tracing, writing to the given file. -func (h *HandlerT) StartGoTrace(file string) error { - h.mu.Lock() - defer h.mu.Unlock() - if h.traceW != nil { - return errors.New("trace already in progress") - } - f, err := os.Create(expandHome(file)) - if err != nil { - return err - } - if err := trace.Start(f); err != nil { - f.Close() - return err - } - h.traceW = f - h.traceFile = file - log.Info("Go tracing started", "dump", h.traceFile) - return nil -} - -// StopTrace stops an ongoing trace. -func (h *HandlerT) StopGoTrace() error { - h.mu.Lock() - defer h.mu.Unlock() - trace.Stop() - if h.traceW == nil { - return errors.New("trace not in progress") - } - log.Info("Done writing Go trace", "dump", h.traceFile) - h.traceW.Close() - h.traceW = nil - h.traceFile = "" - return nil -} diff --git a/evm/go-x1/debug/trace_fallback.go b/evm/go-x1/debug/trace_fallback.go deleted file mode 100644 index ec07d99..0000000 --- a/evm/go-x1/debug/trace_fallback.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build !go1.5 -// +build !go1.5 - -// no-op implementation of tracing methods for Go < 1.5. - -package debug - -import "errors" - -func (*HandlerT) StartGoTrace(string) error { - return errors.New("tracing is not supported on Go < 1.5") -} - -func (*HandlerT) StopGoTrace() error { - return errors.New("tracing is not supported on Go < 1.5") -} diff --git a/evm/go-x1/demo/.gitignore b/evm/go-x1/demo/.gitignore deleted file mode 100644 index 8e1c72a..0000000 --- a/evm/go-x1/demo/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -opera*.datadir -*.log diff --git a/evm/go-x1/demo/README.md b/evm/go-x1/demo/README.md deleted file mode 100755 index 598ec61..0000000 --- a/evm/go-x1/demo/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# Demo - -This directory contains the scripts to run fakenet (private testing network) with N local nodes, -primarily for benchmarking purposes. - -## Scripts - - - start network: `./start.sh`; - - stop network: `./stop.sh`; - - clean data and logs: `./clean.sh`; - -You can specify number of genesis validators by setting N environment variable. - -## Balance transfer example - -from [`demo/`](./demo/) dir - -* Start network: -```sh -N=3 ./start.sh -``` - -* Attach js-console to running node0: -```sh -go run ../cmd/opera attach http://localhost:4000 -``` - -* Check the balance to ensure that node0 has something to transfer (node0 js-console): -```js -ftm.getBalance(ftm.accounts[0]); -``` - - output shows the balance value: -```js -1e+27 -``` - -* Get node1 address: -```sh -go run ../cmd/opera attach --exec "ftm.accounts[0]" http://localhost:4001 -``` - output shows address: -```js -"0x02aff1d0a9ed566e644f06fcfe7efe00a3261d03" -``` - -* Transfer some amount from node0 to node1 address as receiver (node0 js-console): -```js -ftm.sendTransaction( - {from: ftm.accounts[0], to: "0x02aff1d0a9ed566e644f06fcfe7efe00a3261d03", value: "1000000000"}, - function(err, transactionHash) { - if (!err) - console.log(transactionHash + " success"); - }); -``` - output shows unique hash of the outgoing transaction: -```js -0x68a7c1daeee7e7ab5aedf0d0dba337dbf79ce0988387cf6d63ea73b98193adfd success -``` - -* Check the transaction status by its unique hash (js-console): -```sh -ftm.getTransactionReceipt("0x68a7c1daeee7e7ab5aedf0d0dba337dbf79ce0988387cf6d63ea73b98193adfd").blockNumber -``` - output shows number of block, transaction was included in: -``` -174 -``` - -* As soon as transaction is included into a block you will see new balance of both node addresses: -```sh -go run ../cmd/opera attach --exec "ftm.getBalance(ftm.accounts[0])" http://localhost:4000 -go run ../cmd/opera attach --exec "ftm.getBalance(ftm.accounts[0])" http://localhost:4001 -``` - outputs: -```js -9.99999999978999e+26 -1.000000000000001e+27 -``` diff --git a/evm/go-x1/demo/_params.sh b/evm/go-x1/demo/_params.sh deleted file mode 100755 index d5299a7..0000000 --- a/evm/go-x1/demo/_params.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -declare -ri N="${N:-3}" -declare -ri M="${M:-2}" -declare -r TAG="${TAG:-latest}" - -PORT_BASE=3000 -RPCP_BASE=4000 -WSP_BASE=4500 - -attach_and_exec() { - local i=$1 - local CMD=$2 - local RPCP=$(($RPCP_BASE+$i)) - - for attempt in $(seq 40) - do - if (( attempt > 5 )) - then - echo " - attempt ${attempt}: " >&2 - fi - - res=$(../build/demo_opera --exec "${CMD}" attach http://127.0.0.1:${RPCP} 2> /dev/null) - if [ $? -eq 0 ] - then - #echo "success" >&2 - echo $res - return 0 - else - #echo "wait" >&2 - sleep 1 - fi - done - echo "failed RPC connection to ${NAME}" >&2 - return 1 -} diff --git a/evm/go-x1/demo/clean.sh b/evm/go-x1/demo/clean.sh deleted file mode 100755 index 382347e..0000000 --- a/evm/go-x1/demo/clean.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -cd $(dirname $0) - - -rm -fr opera*.datadir -rm *.log -rm ../build/demo_opera diff --git a/evm/go-x1/demo/start.sh b/evm/go-x1/demo/start.sh deleted file mode 100755 index 763c6a5..0000000 --- a/evm/go-x1/demo/start.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -cd $(dirname $0) -. ./_params.sh - -set -e - -echo -e "\nStart $N nodes:\n" - -go build -o ../build/demo_opera ../cmd/opera - -rm -f ./transactions.rlp -for ((i=0;i<$N;i+=1)) -do - DATADIR="${PWD}/opera$i.datadir" - mkdir -p ${DATADIR} - - PORT=$(($PORT_BASE+$i)) - RPCP=$(($RPCP_BASE+$i)) - WSP=$(($WSP_BASE+$i)) - ACC=$(($i+1)) - (../build/demo_opera \ - --datadir=${DATADIR} \ - --fakenet=${ACC}/$N \ - --port=${PORT} \ - --nat extip:127.0.0.1 \ - --http --http.addr="127.0.0.1" --http.port=${RPCP} --http.corsdomain="*" --http.api="eth,debug,net,admin,web3,personal,txpool,ftm,dag" \ - --ws --ws.addr="127.0.0.1" --ws.port=${WSP} --ws.origins="*" --ws.api="eth,debug,net,admin,web3,personal,txpool,ftm,dag" \ - --metrics --metrics.addr=127.0.0.1 --metrics.port=$(($RPCP+1100)) \ - --verbosity=3 --tracing >> opera$i.log 2>&1)& - - echo -e "\tnode$i ok" -done - -echo -e "\nConnect nodes to ring:\n" -for ((i=0;i<$N;i+=1)) -do - for ((n=0;n<$M;n+=1)) - do - j=$(((i+n+1) % N)) - - enode=$(attach_and_exec $j 'admin.nodeInfo.enode') - echo " p2p address = ${enode}" - - echo " connecting node-$i to node-$j:" - res=$(attach_and_exec $i "admin.addPeer(${enode})") - echo " result = ${res}" - done -done diff --git a/evm/go-x1/demo/stop.sh b/evm/go-x1/demo/stop.sh deleted file mode 100755 index 86df52f..0000000 --- a/evm/go-x1/demo/stop.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -killall demo_opera diff --git a/evm/go-x1/docker/Dockerfile.opera b/evm/go-x1/docker/Dockerfile.opera deleted file mode 100644 index 4b29449..0000000 --- a/evm/go-x1/docker/Dockerfile.opera +++ /dev/null @@ -1,22 +0,0 @@ -FROM golang:1.17-alpine as builder - -RUN apk add --no-cache make gcc musl-dev linux-headers git - -WORKDIR /go/go-x1 -COPY . . - -ARG GOPROXY -RUN go mod download -RUN make x1 - - - -FROM alpine:latest - -RUN apk add --no-cache ca-certificates - -COPY --from=builder /go/go-x1/build/x1 / - -EXPOSE 5050 18545 18546 - -ENTRYPOINT ["/x1"] diff --git a/evm/go-x1/ethapi/README.md b/evm/go-x1/ethapi/README.md deleted file mode 100644 index afaf4c4..0000000 --- a/evm/go-x1/ethapi/README.md +++ /dev/null @@ -1 +0,0 @@ -Package is a full copy of github.com/ethereum/go-ethereum/internal/ethapi \ No newline at end of file diff --git a/evm/go-x1/ethapi/abft_api.go b/evm/go-x1/ethapi/abft_api.go deleted file mode 100644 index 08267a4..0000000 --- a/evm/go-x1/ethapi/abft_api.go +++ /dev/null @@ -1,75 +0,0 @@ -package ethapi - -import ( - "context" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rpc" -) - -// PublicAbftAPI provides an API to access consensus related information. -// It offers only methods that operate on public data that is freely available to anyone. -type PublicAbftAPI struct { - b Backend -} - -// NewPublicAbftAPI creates a new SFC protocol API. -func NewPublicAbftAPI(b Backend) *PublicAbftAPI { - return &PublicAbftAPI{b} -} - -func (s *PublicAbftAPI) GetValidators(ctx context.Context, epoch rpc.BlockNumber) (map[hexutil.Uint64]interface{}, error) { - bs, es, err := s.b.GetEpochBlockState(ctx, epoch) - if err != nil { - return nil, err - } - if es == nil { - return nil, nil - } - res := map[hexutil.Uint64]interface{}{} - for _, vid := range es.Validators.IDs() { - profiles := es.ValidatorProfiles - if epoch == rpc.PendingBlockNumber { - profiles = bs.NextValidatorProfiles - } - res[hexutil.Uint64(vid)] = map[string]interface{}{ - "weight": (*hexutil.Big)(profiles[vid].Weight), - "pubkey": profiles[vid].PubKey.String(), - } - } - return res, nil -} - -// GetDowntime returns validator's downtime. -func (s *PublicAbftAPI) GetDowntime(ctx context.Context, validatorID hexutil.Uint) (map[string]interface{}, error) { - blocks, period, err := s.b.GetDowntime(ctx, idx.ValidatorID(validatorID)) - if err != nil { - return nil, err - } - return map[string]interface{}{ - "offlineBlocks": hexutil.Uint64(blocks), - "offlineTime": hexutil.Uint64(period), - }, nil -} - -// GetEpochUptime returns validator's epoch uptime in nanoseconds. -func (s *PublicAbftAPI) GetEpochUptime(ctx context.Context, validatorID hexutil.Uint) (hexutil.Uint64, error) { - v, err := s.b.GetUptime(ctx, idx.ValidatorID(validatorID)) - if err != nil { - return 0, err - } - if v == nil { - return 0, nil - } - return hexutil.Uint64(v.Uint64()), nil -} - -// GetOriginatedEpochFee returns validator's originated epoch fee. -func (s *PublicAbftAPI) GetOriginatedEpochFee(ctx context.Context, validatorID hexutil.Uint) (*hexutil.Big, error) { - v, err := s.b.GetOriginatedFee(ctx, idx.ValidatorID(validatorID)) - if err != nil { - return nil, err - } - return (*hexutil.Big)(v), nil -} diff --git a/evm/go-x1/ethapi/addrlock.go b/evm/go-x1/ethapi/addrlock.go deleted file mode 100644 index 61ddff6..0000000 --- a/evm/go-x1/ethapi/addrlock.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package ethapi - -import ( - "sync" - - "github.com/ethereum/go-ethereum/common" -) - -type AddrLocker struct { - mu sync.Mutex - locks map[common.Address]*sync.Mutex -} - -// lock returns the lock of the given address. -func (l *AddrLocker) lock(address common.Address) *sync.Mutex { - l.mu.Lock() - defer l.mu.Unlock() - if l.locks == nil { - l.locks = make(map[common.Address]*sync.Mutex) - } - if _, ok := l.locks[address]; !ok { - l.locks[address] = new(sync.Mutex) - } - return l.locks[address] -} - -// LockAddr locks an account's mutex. This is used to prevent another tx getting the -// same nonce until the lock is released. The mutex prevents the (an identical nonce) from -// being read again during the time that the first transaction is being signed. -func (l *AddrLocker) LockAddr(address common.Address) { - l.lock(address).Lock() -} - -// UnlockAddr unlocks the mutex of the given account. -func (l *AddrLocker) UnlockAddr(address common.Address) { - l.lock(address).Unlock() -} diff --git a/evm/go-x1/ethapi/api.go b/evm/go-x1/ethapi/api.go deleted file mode 100644 index 1f8f814..0000000 --- a/evm/go-x1/ethapi/api.go +++ /dev/null @@ -1,2159 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package ethapi - -import ( - "context" - "errors" - "fmt" - "math/big" - "math/rand" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/davecgh/go-spew/spew" - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/accounts/scwallet" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/consensus/ethash" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/trie" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/tyler-smith/go-bip39" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/gasprice" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/utils/adapters/ethdb2kvdb" - "github.com/Fantom-foundation/go-opera/utils/dbutil/compactdb" - "github.com/Fantom-foundation/go-opera/utils/signers/gsignercache" - "github.com/Fantom-foundation/go-opera/utils/signers/internaltx" -) - -var ( - noUncles = []evmcore.EvmHeader{} -) - -// PublicEthereumAPI provides an API to access Ethereum related information. -// It offers only methods that operate on public data that is freely available to anyone. -type PublicEthereumAPI struct { - b Backend -} - -// NewPublicEthereumAPI creates a new Ethereum protocol API. -func NewPublicEthereumAPI(b Backend) *PublicEthereumAPI { - return &PublicEthereumAPI{b} -} - -// GasPrice returns a suggestion for a gas price for legacy transactions. -func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { - tipcap := s.b.SuggestGasTipCap(ctx, gasprice.AsDefaultCertainty) - tipcap.Add(tipcap, s.b.MinGasPrice()) - return (*hexutil.Big)(tipcap), nil -} - -// MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions. -func (s *PublicEthereumAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) { - tipcap := s.b.SuggestGasTipCap(ctx, gasprice.AsDefaultCertainty) - return (*hexutil.Big)(tipcap), nil -} - -type feeHistoryResult struct { - OldestBlock *hexutil.Big `json:"oldestBlock"` - Reward [][]*hexutil.Big `json:"reward,omitempty"` - BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"` - GasUsedRatio []float64 `json:"gasUsedRatio"` - Note string `json:"note"` -} - -var errInvalidPercentile = errors.New("invalid reward percentile") - -func (s *PublicEthereumAPI) FeeHistory(ctx context.Context, blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) { - res := &feeHistoryResult{} - res.Reward = make([][]*hexutil.Big, 0, blockCount) - res.BaseFee = make([]*hexutil.Big, 0, blockCount) - res.GasUsedRatio = make([]float64, 0, blockCount) - res.OldestBlock = (*hexutil.Big)(new(big.Int)) - - // validate input parameters - if blockCount == 0 { - return res, nil - } - if blockCount > 1024 { - blockCount = 1024 - } - for i, p := range rewardPercentiles { - if p < 0 || p > 100 { - return nil, fmt.Errorf("%w: %f", errInvalidPercentile, p) - } - if i > 0 && p < rewardPercentiles[i-1] { - return nil, fmt.Errorf("%w: #%d:%f > #%d:%f", errInvalidPercentile, i-1, rewardPercentiles[i-1], i, p) - } - } - last, err := s.b.ResolveRpcBlockNumberOrHash(ctx, rpc.BlockNumberOrHash{BlockNumber: &lastBlock}) - if err != nil { - return nil, err - } - oldest := last - if oldest > idx.Block(blockCount) { - oldest -= idx.Block(blockCount - 1) - } else { - oldest = 0 - } - - baseFee := s.b.MinGasPrice() - - tips := make([]*big.Int, 0, len(rewardPercentiles)) - for _, p := range rewardPercentiles { - tip := s.b.SuggestGasTipCap(ctx, uint64(gasprice.DecimalUnit*p/100.0)) - tips = append(tips, tip) - } - res.OldestBlock.ToInt().SetUint64(uint64(oldest)) - for i := uint64(0); i < uint64(last-oldest+1); i++ { - // randomize the output to mimic the ETH API eth_feeHistory for compatibility reasons - rTips := make([]*hexutil.Big, 0, len(tips)) - for _, t := range tips { - rTip := t - // don't randomize last iteration - if i < uint64(last-oldest) { - // increase by up to 2% randomly - rTip = new(big.Int).Mul(t, big.NewInt(int64(rand.Intn(gasprice.DecimalUnit/50)+gasprice.DecimalUnit))) - rTip.Div(rTip, big.NewInt(gasprice.DecimalUnit)) - } - rTips = append(rTips, (*hexutil.Big)(rTip)) - } - res.Reward = append(res.Reward, rTips) - res.BaseFee = append(res.BaseFee, (*hexutil.Big)(baseFee)) - r := rand.New(rand.NewSource(int64(oldest) + int64(i))) - res.GasUsedRatio = append(res.GasUsedRatio, 0.9+r.Float64()*0.1) - } - res.Note = `In the FTM network, the eth_feeHistory method operates slightly differently due to the network's unique consensus mechanism. ` + - `Here, instead of returning a range of gas tip values from requested blocks, ` + - `it provides a singular estimated gas tip based on a defined confidence level (indicated by the percentile parameter). ` + - `This approach means that while you will receive replicated (and randomized) reward values across the requested blocks, ` + - `the average or median of these values remains consistent with the intended gas tip.` - return res, nil -} - -func (s *PublicEthereumAPI) EffectiveBaseFee(ctx context.Context) *hexutil.Big { - return (*hexutil.Big)(s.b.EffectiveMinGasPrice(ctx)) -} - -// Syncing returns true if node is syncing -func (s *PublicEthereumAPI) Syncing() (interface{}, error) { - progress := s.b.Progress() - // Return not syncing if the synchronisation already completed - if time.Since(progress.CurrentBlockTime.Time()) <= 90*time.Minute { // should be >> MaxEmitInterval - return false, nil - } - // Otherwise gather the block sync stats - return map[string]interface{}{ - "startingBlock": hexutil.Uint64(0), // back-compatibility - "currentEpoch": hexutil.Uint64(progress.CurrentEpoch), - "currentBlock": hexutil.Uint64(progress.CurrentBlock), - "currentBlockHash": progress.CurrentBlockHash.Hex(), - "currentBlockTime": hexutil.Uint64(progress.CurrentBlockTime), - "highestBlock": hexutil.Uint64(progress.HighestBlock), - "highestEpoch": hexutil.Uint64(progress.HighestEpoch), - "pulledStates": hexutil.Uint64(0), // back-compatibility - "knownStates": hexutil.Uint64(0), // back-compatibility - }, nil -} - -// PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. -type PublicTxPoolAPI struct { - b Backend -} - -// NewPublicTxPoolAPI creates a new tx pool service that gives information about the transaction pool. -func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI { - return &PublicTxPoolAPI{b} -} - -// Content returns the transactions contained within the transaction pool. -func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { - content := map[string]map[string]map[string]*RPCTransaction{ - "pending": make(map[string]map[string]*RPCTransaction), - "queued": make(map[string]map[string]*RPCTransaction), - } - pending, queue := s.b.TxPoolContent() - - curHeader := s.b.CurrentBlock().Header() - // Flatten the pending transactions - for account, txs := range pending { - dump := make(map[string]*RPCTransaction) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader.BaseFee) - } - content["pending"][account.Hex()] = dump - } - // Flatten the queued transactions - for account, txs := range queue { - dump := make(map[string]*RPCTransaction) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader.BaseFee) - } - content["queued"][account.Hex()] = dump - } - return content -} - -// ContentFrom returns the transactions contained within the transaction pool. -func (s *PublicTxPoolAPI) ContentFrom(addr common.Address) map[string]map[string]*RPCTransaction { - content := make(map[string]map[string]*RPCTransaction, 2) - pending, queue := s.b.TxPoolContentFrom(addr) - curHeader := s.b.CurrentBlock().Header() - - // Build the pending transactions - dump := make(map[string]*RPCTransaction, len(pending)) - for _, tx := range pending { - dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader.BaseFee) - } - content["pending"] = dump - - // Build the queued transactions - dump = make(map[string]*RPCTransaction, len(queue)) - for _, tx := range queue { - dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader.BaseFee) - } - content["queued"] = dump - - return content -} - -// Status returns the number of pending and queued transaction in the pool. -func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint { - pending, queue := s.b.Stats() - return map[string]hexutil.Uint{ - "pending": hexutil.Uint(pending), - "queued": hexutil.Uint(queue), - } -} - -// Inspect retrieves the content of the transaction pool and flattens it into an -// easily inspectable list. -func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string { - content := map[string]map[string]map[string]string{ - "pending": make(map[string]map[string]string), - "queued": make(map[string]map[string]string), - } - pending, queue := s.b.TxPoolContent() - - // Define a formatter to flatten a transaction into a string - var format = func(tx *types.Transaction) string { - if to := tx.To(); to != nil { - return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) - } - return fmt.Sprintf("contract creation: %v wei + %v gas × %v wei", tx.Value(), tx.Gas(), tx.GasPrice()) - } - // Flatten the pending transactions - for account, txs := range pending { - dump := make(map[string]string) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) - } - content["pending"][account.Hex()] = dump - } - // Flatten the queued transactions - for account, txs := range queue { - dump := make(map[string]string) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) - } - content["queued"][account.Hex()] = dump - } - return content -} - -// PublicAccountAPI provides an API to access accounts managed by this node. -// It offers only methods that can retrieve accounts. -type PublicAccountAPI struct { - am *accounts.Manager -} - -// NewPublicAccountAPI creates a new PublicAccountAPI. -func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { - return &PublicAccountAPI{am: am} -} - -// Accounts returns the collection of accounts this node manages -func (s *PublicAccountAPI) Accounts() []common.Address { - return s.am.Accounts() -} - -// PrivateAccountAPI provides an API to access accounts managed by this node. -// It offers methods to create, (un)lock en list accounts. Some methods accept -// passwords and are therefore considered private by default. -type PrivateAccountAPI struct { - am *accounts.Manager - nonceLock *AddrLocker - b Backend -} - -// NewPrivateAccountAPI create a new PrivateAccountAPI. -func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI { - return &PrivateAccountAPI{ - am: b.AccountManager(), - nonceLock: nonceLock, - b: b, - } -} - -// ListAccounts will return a list of addresses for accounts this node manages. -func (s *PrivateAccountAPI) ListAccounts() []common.Address { - return s.am.Accounts() -} - -// RawWallet is a JSON representation of an accounts.Wallet interface, with its -// data contents extracted into plain fields. -type RawWallet struct { - URL string `json:"url"` - Status string `json:"status"` - Failure string `json:"failure,omitempty"` - Accounts []accounts.Account `json:"accounts,omitempty"` -} - -// ListWallets will return a list of wallets this node manages. -func (s *PrivateAccountAPI) ListWallets() []RawWallet { - wallets := make([]RawWallet, 0) // return [] instead of nil if empty - for _, wallet := range s.am.Wallets() { - status, failure := wallet.Status() - - raw := RawWallet{ - URL: wallet.URL().String(), - Status: status, - Accounts: wallet.Accounts(), - } - if failure != nil { - raw.Failure = failure.Error() - } - wallets = append(wallets, raw) - } - return wallets -} - -// OpenWallet initiates a hardware wallet opening procedure, establishing a USB -// connection and attempting to authenticate via the provided passphrase. Note, -// the method may return an extra challenge requiring a second open (e.g. the -// Trezor PIN matrix challenge). -func (s *PrivateAccountAPI) OpenWallet(url string, passphrase *string) error { - wallet, err := s.am.Wallet(url) - if err != nil { - return err - } - pass := "" - if passphrase != nil { - pass = *passphrase - } - return wallet.Open(pass) -} - -// DeriveAccount requests a HD wallet to derive a new account, optionally pinning -// it for later reuse. -func (s *PrivateAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { - wallet, err := s.am.Wallet(url) - if err != nil { - return accounts.Account{}, err - } - derivPath, err := accounts.ParseDerivationPath(path) - if err != nil { - return accounts.Account{}, err - } - if pin == nil { - pin = new(bool) - } - return wallet.Derive(derivPath, *pin) -} - -// NewAccount will create a new account and returns the address for the new account. -func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { - ks, err := fetchKeystore(s.am) - if err != nil { - return common.Address{}, err - } - acc, err := ks.NewAccount(password) - if err == nil { - log.Info("Your new key was generated", "address", acc.Address) - log.Warn("Please backup your key file!", "path", acc.URL.Path) - log.Warn("Please remember your password!") - return acc.Address, nil - } - return common.Address{}, err -} - -// fetchKeystore retrieves the encrypted keystore from the account manager. -func fetchKeystore(am *accounts.Manager) (*keystore.KeyStore, error) { - if ks := am.Backends(keystore.KeyStoreType); len(ks) > 0 { - return ks[0].(*keystore.KeyStore), nil - } - return nil, errors.New("local keystore not used") -} - -// ImportRawKey stores the given hex encoded ECDSA key into the key directory, -// encrypting it with the passphrase. -func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { - key, err := crypto.HexToECDSA(privkey) - if err != nil { - return common.Address{}, err - } - ks, err := fetchKeystore(s.am) - if err != nil { - return common.Address{}, err - } - acc, err := ks.ImportECDSA(key, password) - return acc.Address, err -} - -// UnlockAccount will unlock the account associated with the given address with -// the given password for duration seconds. If duration is nil it will use a -// default of 300 seconds. It returns an indication if the account was unlocked. -func (s *PrivateAccountAPI) UnlockAccount(ctx context.Context, addr common.Address, password string, duration *uint64) (bool, error) { - // When the API is exposed by external RPC(http, ws etc), unless the user - // explicitly specifies to allow the insecure account unlocking, otherwise - // it is disabled. - if s.b.ExtRPCEnabled() && !s.b.AccountManager().Config().InsecureUnlockAllowed { - return false, errors.New("account unlock with HTTP access is forbidden") - } - - const max = uint64(time.Duration(math.MaxInt64) / time.Second) - var d time.Duration - if duration == nil { - d = 300 * time.Second - } else if *duration > max { - return false, errors.New("unlock duration too large") - } else { - d = time.Duration(*duration) * time.Second - } - ks, err := fetchKeystore(s.am) - if err != nil { - return false, err - } - err = ks.TimedUnlock(accounts.Account{Address: addr}, password, d) - if err != nil { - log.Warn("Failed account unlock attempt", "address", addr, "err", err) - } - return err == nil, err -} - -// LockAccount will lock the account associated with the given address when it's unlocked. -func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { - if ks, err := fetchKeystore(s.am); err == nil { - return ks.Lock(addr) == nil - } - return false -} - -// signTransaction sets defaults and signs the given transaction -// NOTE: the caller needs to ensure that the nonceLock is held, if applicable, -// and release it after the transaction has been submitted to the tx pool -func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *TransactionArgs, passwd string) (*types.Transaction, error) { - // Look up the wallet containing the requested signer - account := accounts.Account{Address: args.from()} - wallet, err := s.am.Find(account) - if err != nil { - return nil, err - } - // Set some sanity defaults and terminate on failure - if err := args.setDefaults(ctx, s.b); err != nil { - return nil, err - } - // Assemble the transaction and sign with the wallet - tx := args.toTransaction() - - return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID) -} - -// SendTransaction will create a transaction from the given arguments and -// tries to sign it with the key associated with args.From. If the given -// passwd isn't able to decrypt the key it fails. -func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args TransactionArgs, passwd string) (common.Hash, error) { - if args.Nonce == nil { - // Hold the addresse's mutex around signing to prevent concurrent assignment of - // the same nonce to multiple accounts. - s.nonceLock.LockAddr(args.from()) - defer s.nonceLock.UnlockAddr(args.from()) - } - signed, err := s.signTransaction(ctx, &args, passwd) - if err != nil { - log.Warn("Failed transaction send attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err) - return common.Hash{}, err - } - return SubmitTransaction(ctx, s.b, signed) -} - -// SignTransaction will create a transaction from the given arguments and -// tries to sign it with the key associated with args.From. If the given passwd isn't -// able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast -// to other nodes -func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args TransactionArgs, passwd string) (*SignTransactionResult, error) { - // No need to obtain the noncelock mutex, since we won't be sending this - // tx into the transaction pool, but right back to the user - if args.From == nil { - return nil, fmt.Errorf("sender not specified") - } - if args.Gas == nil { - return nil, fmt.Errorf("gas not specified") - } - if args.GasPrice == nil && (args.MaxFeePerGas == nil || args.MaxPriorityFeePerGas == nil) { - return nil, fmt.Errorf("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas") - } - if args.Nonce == nil { - return nil, fmt.Errorf("nonce not specified") - } - // Before actually signing the transaction, ensure the transaction fee is reasonable. - tx := args.toTransaction() - if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil { - return nil, err - } - signed, err := s.signTransaction(ctx, &args, passwd) - if err != nil { - log.Warn("Failed transaction sign attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err) - return nil, err - } - data, err := signed.MarshalBinary() - if err != nil { - return nil, err - } - return &SignTransactionResult{data, signed}, nil -} - -// Sign calculates an Ethereum ECDSA signature for: -// keccack256("\x19Ethereum Signed Message:\n" + len(message) + message)) -// -// Note, the produced signature conforms to the secp256k1 curve R, S and V values, -// where the V value will be 27 or 28 for legacy reasons. -// -// The key used to calculate the signature is decrypted with the given password. -// -// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign -func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { - // Look up the wallet containing the requested signer - account := accounts.Account{Address: addr} - - wallet, err := s.b.AccountManager().Find(account) - if err != nil { - return nil, err - } - // Assemble sign the data with the wallet - signature, err := wallet.SignTextWithPassphrase(account, passwd, data) - if err != nil { - log.Warn("Failed data sign attempt", "address", addr, "err", err) - return nil, err - } - signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper - return signature, nil -} - -// EcRecover returns the address for the account that was used to create the signature. -// Note, this function is compatible with eth_sign and personal_sign. As such it recovers -// the address of: -// hash = keccak256("\x19Ethereum Signed Message:\n"${message length}${message}) -// addr = ecrecover(hash, signature) -// -// Note, the signature must conform to the secp256k1 curve R, S and V values, where -// the V value must be 27 or 28 for legacy reasons. -// -// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover -func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { - if len(sig) != crypto.SignatureLength { - return common.Address{}, fmt.Errorf("signature must be %d bytes long", crypto.SignatureLength) - } - if sig[crypto.RecoveryIDOffset] != 27 && sig[crypto.RecoveryIDOffset] != 28 { - return common.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)") - } - sig[crypto.RecoveryIDOffset] -= 27 // Transform yellow paper V from 27/28 to 0/1 - - rpk, err := crypto.SigToPub(accounts.TextHash(data), sig) - if err != nil { - return common.Address{}, err - } - return crypto.PubkeyToAddress(*rpk), nil -} - -// SignAndSendTransaction was renamed to SendTransaction. This method is deprecated -// and will be removed in the future. It primary goal is to give clients time to update. -func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args TransactionArgs, passwd string) (common.Hash, error) { - return s.SendTransaction(ctx, args, passwd) -} - -// InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key. -func (s *PrivateAccountAPI) InitializeWallet(ctx context.Context, url string) (string, error) { - wallet, err := s.am.Wallet(url) - if err != nil { - return "", err - } - - entropy, err := bip39.NewEntropy(256) - if err != nil { - return "", err - } - - mnemonic, err := bip39.NewMnemonic(entropy) - if err != nil { - return "", err - } - - seed := bip39.NewSeed(mnemonic, "") - - switch wallet := wallet.(type) { - case *scwallet.Wallet: - return mnemonic, wallet.Initialize(seed) - default: - return "", fmt.Errorf("specified wallet does not support initialization") - } -} - -// Unpair deletes a pairing between wallet and geth. -func (s *PrivateAccountAPI) Unpair(ctx context.Context, url string, pin string) error { - wallet, err := s.am.Wallet(url) - if err != nil { - return err - } - - switch wallet := wallet.(type) { - case *scwallet.Wallet: - return wallet.Unpair([]byte(pin)) - default: - return fmt.Errorf("specified wallet does not support pairing") - } -} - -// PublicBlockChainAPI provides an API to access the Ethereum blockchain. -// It offers only methods that operate on public data that is freely available to anyone. -type PublicBlockChainAPI struct { - b Backend -} - -// NewPublicBlockChainAPI creates a new Ethereum blockchain API. -func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { - return &PublicBlockChainAPI{b} -} - -// CurrentEpoch returns current epoch number. -func (s *PublicBlockChainAPI) CurrentEpoch(ctx context.Context) hexutil.Uint64 { - return hexutil.Uint64(s.b.CurrentEpoch(ctx)) -} - -// GetRules returns network rules for an epoch -func (s *PublicBlockChainAPI) GetRules(ctx context.Context, epoch rpc.BlockNumber) (*opera.Rules, error) { - _, es, err := s.b.GetEpochBlockState(ctx, epoch) - if err != nil { - return nil, err - } - if es == nil { - return nil, nil - } - return &es.Rules, nil -} - -// GetEpochBlock returns block height in a beginning of an epoch -func (s *PublicBlockChainAPI) GetEpochBlock(ctx context.Context, epoch rpc.BlockNumber) (hexutil.Uint64, error) { - bs, _, err := s.b.GetEpochBlockState(ctx, epoch) - if err != nil { - return 0, err - } - if bs == nil { - return 0, nil - } - return hexutil.Uint64(bs.LastBlock.Idx), nil -} - -// ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config. -func (api *PublicBlockChainAPI) ChainId() (*hexutil.Big, error) { - // if current block is at or past the EIP-155 replay-protection fork block, return chainID from config - if config := api.b.ChainConfig(); config.IsEIP155(api.b.CurrentBlock().Number) { - return (*hexutil.Big)(config.ChainID), nil - } - return nil, fmt.Errorf("chain not synced beyond EIP-155 replay-protection fork block") -} - -// BlockNumber returns the block number of the chain head. -func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { - header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available - return hexutil.Uint64(header.Number.Uint64()) -} - -// GetBalance returns the amount of wei for the given address in the state of the -// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta -// block numbers are also allowed. -func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { - return nil, err - } - return (*hexutil.Big)(state.GetBalance(address)), state.Error() -} - -// AccountResult is result struct for GetProof -type AccountResult struct { - Address common.Address `json:"address"` - AccountProof []string `json:"accountProof"` - Balance *hexutil.Big `json:"balance"` - CodeHash common.Hash `json:"codeHash"` - Nonce hexutil.Uint64 `json:"nonce"` - StorageHash common.Hash `json:"storageHash"` - StorageProof []StorageResult `json:"storageProof"` -} - -// StorageResult is result struct for GetProof -type StorageResult struct { - Key string `json:"key"` - Value *hexutil.Big `json:"value"` - Proof []string `json:"proof"` -} - -// GetProof returns the Merkle-proof for a given account and optionally some storage keys. -func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { - return nil, err - } - - storageTrie := state.StorageTrie(address) - storageHash := types.EmptyRootHash - codeHash := state.GetCodeHash(address) - storageProof := make([]StorageResult, len(storageKeys)) - - // if we have a storageTrie, (which means the account exists), we can update the storagehash - if storageTrie != nil { - storageHash = storageTrie.Hash() - } else { - // no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray. - codeHash = crypto.Keccak256Hash(nil) - } - - // create the proof for the storageKeys - for i, key := range storageKeys { - if storageTrie != nil { - proof, storageError := state.GetStorageProof(address, common.HexToHash(key)) - if storageError != nil { - return nil, storageError - } - storageProof[i] = StorageResult{key, (*hexutil.Big)(state.GetState(address, common.HexToHash(key)).Big()), toHexSlice(proof)} - } else { - storageProof[i] = StorageResult{key, &hexutil.Big{}, []string{}} - } - } - - // create the accountProof - accountProof, proofErr := state.GetProof(address) - if proofErr != nil { - return nil, proofErr - } - - return &AccountResult{ - Address: address, - AccountProof: toHexSlice(accountProof), - Balance: (*hexutil.Big)(state.GetBalance(address)), - CodeHash: codeHash, - Nonce: hexutil.Uint64(state.GetNonce(address)), - StorageHash: storageHash, - StorageProof: storageProof, - }, state.Error() -} - -// GetHeaderByNumber returns the requested canonical block header. -// * When blockNr is -1 the chain head is returned. -// * When blockNr is -2 the pending chain head is returned. -func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { - header, err := s.b.HeaderByNumber(ctx, number) - if header != nil && err == nil { - response := s.rpcMarshalHeader(header, s.calculateExtBlockApi(ctx, number)) - if number == rpc.PendingBlockNumber { - // Pending header need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - return response, err - } - return nil, err -} - -// GetHeaderByHash returns the requested header by hash. -func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { - header, _ := s.b.HeaderByHash(ctx, hash) - if header != nil { - return s.rpcMarshalHeader(header, s.calculateExtBlockApi(ctx, rpc.BlockNumber(header.Number.Uint64()))) - } - return nil -} - -func (s *PublicBlockChainAPI) calculateExtBlockApi(ctx context.Context, blkNumber rpc.BlockNumber) extBlockApi { - var ext extBlockApi - if s.b.CalcBlockExtApi() && blkNumber != rpc.EarliestBlockNumber { - receipts, err := s.b.GetReceiptsByNumber(ctx, blkNumber) - if err != nil { - return ext - } - if receipts.Len() != 0 { - ext.receiptsRoot = types.DeriveSha(receipts, trie.NewStackTrie(nil)) - ext.bloom = types.CreateBloom(receipts) - } else { - ext.receiptsRoot = types.EmptyRootHash - } - } - return ext -} - -// GetBlockByNumber returns the requested canonical block. -// - When blockNr is -1 the chain head is returned. -// - When blockNr is -2 the pending chain head is returned. -// - When fullTx is true all transactions in the block are returned, otherwise -// only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { - block, err := s.b.BlockByNumber(ctx, number) - if block != nil && err == nil { - response, err := s.rpcMarshalBlock(block, s.calculateExtBlockApi(ctx, number), true, fullTx) - if err == nil && number == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - return response, err - } - return nil, err -} - -// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full -// detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { - block, err := s.b.BlockByHash(ctx, hash) - if block != nil { - return s.rpcMarshalBlock(block, s.calculateExtBlockApi(ctx, rpc.BlockNumber(block.NumberU64())), true, fullTx) - } - return nil, err -} - -// GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true -// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { - block, err := s.b.BlockByNumber(ctx, blockNr) - if block != nil { - log.Debug("Requested uncle not found", "number", blockNr, "hash", block.Hash, "index", index) - return nil, nil - } - return nil, err -} - -// GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true -// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { - block, err := s.b.BlockByHash(ctx, blockHash) - if block != nil { - log.Debug("Requested uncle not found", "number", block.Number, "hash", blockHash, "index", index) - return nil, nil - } - return nil, err -} - -// GetUncleCountByBlockNumber returns number of uncles in the block for the given block number -func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { - if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { - n := hexutil.Uint(len(noUncles)) - return &n - } - return nil -} - -// GetUncleCountByBlockHash returns number of uncles in the block for the given block hash -func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { - if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { - n := hexutil.Uint(len(noUncles)) - return &n - } - return nil -} - -// GetCode returns the code stored at the given address in the state for the given block number. -func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { - return nil, err - } - code := state.GetCode(address) - return code, state.Error() -} - -// GetStorageAt returns the storage from the state at the given address, key and -// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block -// numbers are also allowed. -func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNr rpc.BlockNumberOrHash) (hexutil.Bytes, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNr) - if state == nil || err != nil { - return nil, err - } - res := state.GetState(address, common.HexToHash(key)) - return res[:], state.Error() -} - -// OverrideAccount indicates the overriding fields of account during the execution -// of a message call. -// Note, state and stateDiff can't be specified at the same time. If state is -// set, message execution will only use the data in the given state. Otherwise -// if statDiff is set, all diff will be applied first and then execute the call -// message. -type OverrideAccount struct { - Nonce *hexutil.Uint64 `json:"nonce"` - Code *hexutil.Bytes `json:"code"` - Balance **hexutil.Big `json:"balance"` - State *map[common.Hash]common.Hash `json:"state"` - StateDiff *map[common.Hash]common.Hash `json:"stateDiff"` -} - -// StateOverride is the collection of overridden accounts. -type StateOverride map[common.Address]OverrideAccount - -// Apply overrides the fields of specified accounts into the given state. -func (diff *StateOverride) Apply(state *state.StateDB) error { - if diff == nil { - return nil - } - for addr, account := range *diff { - // Override account nonce. - if account.Nonce != nil { - state.SetNonce(addr, uint64(*account.Nonce)) - } - // Override account(contract) code. - if account.Code != nil { - state.SetCode(addr, *account.Code) - } - // Override account balance. - if account.Balance != nil { - state.SetBalance(addr, (*big.Int)(*account.Balance)) - } - if account.State != nil && account.StateDiff != nil { - return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex()) - } - // Replace entire state if caller requires. - if account.State != nil { - state.SetStorage(addr, *account.State) - } - // Apply state diff into specified accounts. - if account.StateDiff != nil { - for key, value := range *account.StateDiff { - state.SetState(addr, key, value) - } - } - } - return nil -} - -func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*evmcore.ExecutionResult, error) { - defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) - - state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { - return nil, err - } - if err := overrides.Apply(state); err != nil { - return nil, err - } - // Setup context so it may be cancelled the call has completed - // or, in case of unmetered gas, setup a context with a timeout. - var cancel context.CancelFunc - if timeout > 0 { - ctx, cancel = context.WithTimeout(ctx, timeout) - } else { - ctx, cancel = context.WithCancel(ctx) - } - // Make sure the context is cancelled when the call has completed - // this makes sure resources are cleaned up. - defer cancel() - - // Get a new instance of the EVM. - msg, err := args.ToMessage(globalGasCap, header.BaseFee) - if err != nil { - return nil, err - } - vmConfig := opera.DefaultVMConfig - vmConfig.NoBaseFee = true - evm, vmError, err := b.GetEVM(ctx, msg, state, header, &vmConfig) - if err != nil { - return nil, err - } - // Wait for the context to be done and cancel the evm. Even if the - // EVM has finished, cancelling may be done (repeatedly) - go func() { - <-ctx.Done() - evm.Cancel() - }() - - // Execute the message. - gp := new(evmcore.GasPool).AddGas(math.MaxUint64) - result, err := evmcore.ApplyMessage(evm, msg, gp) - if err := vmError(); err != nil { - return nil, err - } - - // If the timer caused an abort, return an appropriate error message - if evm.Cancelled() { - return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) - } - if err != nil { - return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()) - } - return result, nil -} - -func newRevertError(result *evmcore.ExecutionResult) *revertError { - reason, errUnpack := abi.UnpackRevert(result.Revert()) - err := errors.New("execution reverted") - if errUnpack == nil { - err = fmt.Errorf("execution reverted: %v", reason) - } - return &revertError{ - error: err, - reason: hexutil.Encode(result.Revert()), - } -} - -// revertError is an API error that encompassas an EVM revertal with JSON error -// code and a binary data blob. -type revertError struct { - error - reason string // revert reason hex encoded -} - -// ErrorCode returns the JSON error code for a revertal. -// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal -func (e *revertError) ErrorCode() int { - return 3 -} - -// ErrorData returns the hex encoded revert reason. -func (e *revertError) ErrorData() interface{} { - return e.reason -} - -// Call executes the given transaction on the state for the given block number. -// -// Additionally, the caller can specify a batch of contract for fields overriding. -// -// Note, this function doesn't make and changes in the state/blockchain and is -// useful to execute and retrieve values. -func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) { - result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap()) - if err != nil { - return nil, err - } - // If the result contains a revert reason, try to unpack and return it. - if len(result.Revert()) > 0 { - return nil, newRevertError(result) - } - return result.Return(), result.Err -} - -// DoEstimateGas - binary search the gas requirement, as it may be higher than the amount used -func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) { - // Binary search the gas requirement, as it may be higher than the amount used - var ( - lo uint64 = params.TxGas - 1 - hi uint64 - cap uint64 - ) - // Use zero address if sender unspecified. - if args.From == nil { - args.From = new(common.Address) - } - // Determine the highest gas limit can be used during the estimation. - if args.Gas != nil && uint64(*args.Gas) >= params.TxGas { - hi = uint64(*args.Gas) - } else { - hi = b.MaxGasLimit() - } - // Normalize the max fee per gas the call is willing to spend. - var feeCap *big.Int - if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { - return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") - } else if args.GasPrice != nil { - feeCap = args.GasPrice.ToInt() - } else if args.MaxFeePerGas != nil { - feeCap = args.MaxFeePerGas.ToInt() - } else { - feeCap = common.Big0 - } - // Recap the highest gas limit with account's available balance. - if feeCap.BitLen() != 0 { - state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { - return 0, err - } - balance := state.GetBalance(*args.From) // from can't be nil - available := new(big.Int).Set(balance) - if args.Value != nil { - if args.Value.ToInt().Cmp(available) >= 0 { - return 0, errors.New("insufficient funds for transfer") - } - available.Sub(available, args.Value.ToInt()) - } - allowance := new(big.Int).Div(available, feeCap) - - // If the allowance is larger than maximum uint64, skip checking - if allowance.IsUint64() && hi > allowance.Uint64() { - transfer := args.Value - if transfer == nil { - transfer = new(hexutil.Big) - } - log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance, - "sent", transfer.ToInt(), "maxFeePerGas", feeCap, "fundable", allowance) - hi = allowance.Uint64() - } - } - // Recap the highest gas allowance with specified gascap. - if gasCap != 0 && hi > gasCap { - log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap) - hi = gasCap - } - cap = hi - - // Create a helper to check if a gas allowance results in an executable transaction - executable := func(gas uint64) (bool, *evmcore.ExecutionResult, error) { - args.Gas = (*hexutil.Uint64)(&gas) - - result, err := DoCall(ctx, b, args, blockNrOrHash, nil, 0, gasCap) - if err != nil { - if errors.Is(err, evmcore.ErrIntrinsicGas) { - return true, nil, nil // Special case, raise gas limit - } - return true, nil, err // Bail out - } - return result.Failed(), result, nil - } - // Execute the binary search and hone in on an executable gas limit - for lo+1 < hi { - mid := (hi + lo) / 2 - failed, _, err := executable(mid) - - // If the error is not nil(consensus error), it means the provided message - // call or transaction will never be accepted no matter how much gas it is - // assigned. Return the error directly, don't struggle any more. - if err != nil { - return 0, err - } - if failed { - lo = mid - } else { - hi = mid - } - } - // Reject the transaction as invalid if it still fails at the highest allowance - if hi == cap { - failed, result, err := executable(hi) - if err != nil { - return 0, err - } - if failed { - if result != nil && result.Err != vm.ErrOutOfGas { - if len(result.Revert()) > 0 { - return 0, newRevertError(result) - } - return 0, result.Err - } - // Otherwise, the specified gas cap is too low - return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) - } - } - return hexutil.Uint64(hi), nil -} - -// EstimateGas returns an estimate of the amount of gas needed to execute the -// given transaction against the current pending block. -func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { - bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) - if blockNrOrHash != nil { - bNrOrHash = *blockNrOrHash - } - return DoEstimateGas(ctx, s.b, args, bNrOrHash, s.b.RPCGasCap()) -} - -// ExecutionResult groups all structured logs emitted by the EVM -// while replaying a transaction in debug mode as well as transaction -// execution status, the amount of gas used and the return value -type ExecutionResult struct { - Gas uint64 `json:"gas"` - Failed bool `json:"failed"` - ReturnValue string `json:"returnValue"` - StructLogs []StructLogRes `json:"structLogs"` -} - -// StructLogRes stores a structured log emitted by the EVM while replaying a -// transaction in debug mode -type StructLogRes struct { - Pc uint64 `json:"pc"` - Op string `json:"op"` - Gas uint64 `json:"gas"` - GasCost uint64 `json:"gasCost"` - Depth int `json:"depth"` - Error string `json:"error,omitempty"` - Stack *[]string `json:"stack,omitempty"` - Memory *[]string `json:"memory,omitempty"` - Storage *map[string]string `json:"storage,omitempty"` -} - -// FormatLogs formats EVM returned structured logs for json output -func FormatLogs(logs []vm.StructLog) []StructLogRes { - formatted := make([]StructLogRes, len(logs)) - for index, trace := range logs { - formatted[index] = StructLogRes{ - Pc: trace.Pc, - Op: trace.Op.String(), - Gas: trace.Gas, - GasCost: trace.GasCost, - Depth: trace.Depth, - Error: trace.ErrorString(), - } - if trace.Stack != nil { - stack := make([]string, len(trace.Stack)) - for i, stackValue := range trace.Stack { - stack[i] = stackValue.Hex() - } - formatted[index].Stack = &stack - } - if trace.Memory != nil { - memory := make([]string, 0, (len(trace.Memory)+31)/32) - for i := 0; i+32 <= len(trace.Memory); i += 32 { - memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) - } - formatted[index].Memory = &memory - } - if trace.Storage != nil { - storage := make(map[string]string) - for i, storageValue := range trace.Storage { - storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) - } - formatted[index].Storage = &storage - } - } - return formatted -} - -type extBlockApi struct { - bloom types.Bloom - receiptsRoot common.Hash -} - -// RPCMarshalHeader converts the given header to the RPC output . -func RPCMarshalHeader(head *evmcore.EvmHeader, ext extBlockApi) map[string]interface{} { - result := map[string]interface{}{ - "number": (*hexutil.Big)(head.Number), - "epoch": hexutil.Uint64(hash.Event(head.Hash).Epoch()), - "hash": head.Hash, // store EvmBlock's hash in extra, because extra is always empty - "parentHash": head.ParentHash, - "nonce": types.BlockNonce{}, - "mixHash": common.Hash{}, - "sha3Uncles": types.EmptyUncleHash, - "logsBloom": ext.bloom, - "stateRoot": head.Root, - "miner": head.Coinbase, - "difficulty": (*hexutil.Big)(new(big.Int)), - "extraData": hexutil.Bytes([]byte{}), - "size": hexutil.Uint64(head.EthHeader().Size()), - "gasLimit": hexutil.Uint64(0xffffffffffff), // don't use too much bits here to avoid parsing issues - "gasUsed": hexutil.Uint64(head.GasUsed), - "timestamp": hexutil.Uint64(head.Time.Unix()), - "timestampNano": hexutil.Uint64(head.Time), - "transactionsRoot": head.TxHash, - "receiptsRoot": ext.receiptsRoot, - } - if head.BaseFee != nil { - result["baseFeePerGas"] = (*hexutil.Big)(head.BaseFee) - } - return result -} - -// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are -// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain -// transaction hashes. -func RPCMarshalBlock(block *evmcore.EvmBlock, ext extBlockApi, inclTx bool, fullTx bool) (map[string]interface{}, error) { - fields := RPCMarshalHeader(block.Header(), ext) - fields["size"] = hexutil.Uint64(block.EthBlock().Size()) - - if inclTx { - formatTx := func(tx *types.Transaction) (interface{}, error) { - return tx.Hash(), nil - } - if fullTx { - formatTx = func(tx *types.Transaction) (interface{}, error) { - return newRPCTransactionFromBlockHash(block, tx.Hash()), nil - } - } - txs := block.Transactions - transactions := make([]interface{}, len(txs)) - var err error - for i, tx := range txs { - if transactions[i], err = formatTx(tx); err != nil { - return nil, err - } - } - fields["transactions"] = transactions - } - uncles := noUncles - uncleHashes := make([]common.Hash, len(uncles)) - for i, uncle := range uncles { - uncleHashes[i] = uncle.Hash - } - fields["uncles"] = uncleHashes - - return fields, nil -} - -// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires -// a `PublicBlockchainAPI`. -func (s *PublicBlockChainAPI) rpcMarshalHeader(header *evmcore.EvmHeader, ext extBlockApi) map[string]interface{} { - fields := RPCMarshalHeader(header, ext) - fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(header.Hash)) - return fields -} - -// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires -// a `PublicBlockchainAPI`. -func (s *PublicBlockChainAPI) rpcMarshalBlock(b *evmcore.EvmBlock, ext extBlockApi, inclTx bool, fullTx bool) (map[string]interface{}, error) { - fields, err := RPCMarshalBlock(b, ext, inclTx, fullTx) - if err != nil { - return nil, err - } - fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(b.Hash)) - return fields, err -} - -// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction -type RPCTransaction struct { - BlockHash *common.Hash `json:"blockHash"` - BlockNumber *hexutil.Big `json:"blockNumber"` - From common.Address `json:"from"` - Gas hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` - GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` - Hash common.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` - Nonce hexutil.Uint64 `json:"nonce"` - To *common.Address `json:"to"` - TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` - Value *hexutil.Big `json:"value"` - Type hexutil.Uint64 `json:"type"` - Accesses *types.AccessList `json:"accessList,omitempty"` - ChainID *hexutil.Big `json:"chainId,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` -} - -// newRPCTransaction returns a transaction that will serialize to the RPC -// representation, with the given location metadata set (if available). -func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int) *RPCTransaction { - // Determine the signer. For replay-protected transactions, use the most permissive - // signer, because we assume that signers are backwards-compatible with old - // transactions. For non-protected transactions, the homestead signer signer is used - // because the return value of ChainId is zero for those transactions. - var signer types.Signer - if tx.Protected() { - signer = gsignercache.Wrap(types.LatestSignerForChainID(tx.ChainId())) - } else { - signer = gsignercache.Wrap(types.HomesteadSigner{}) - } - from, _ := internaltx.Sender(signer, tx) - v, r, s := tx.RawSignatureValues() - result := &RPCTransaction{ - Type: hexutil.Uint64(tx.Type()), - From: from, - Gas: hexutil.Uint64(tx.Gas()), - GasPrice: (*hexutil.Big)(tx.GasPrice()), - Hash: tx.Hash(), - Input: hexutil.Bytes(tx.Data()), - Nonce: hexutil.Uint64(tx.Nonce()), - To: tx.To(), - Value: (*hexutil.Big)(tx.Value()), - V: (*hexutil.Big)(v), - R: (*hexutil.Big)(r), - S: (*hexutil.Big)(s), - } - if blockHash != (common.Hash{}) { - result.BlockHash = &blockHash - result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) - result.TransactionIndex = (*hexutil.Uint64)(&index) - } - switch tx.Type() { - case types.AccessListTxType: - al := tx.AccessList() - result.Accesses = &al - result.ChainID = (*hexutil.Big)(tx.ChainId()) - case types.DynamicFeeTxType: - al := tx.AccessList() - result.Accesses = &al - result.ChainID = (*hexutil.Big)(tx.ChainId()) - result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap()) - result.GasTipCap = (*hexutil.Big)(tx.GasTipCap()) - // if the transaction has been mined, compute the effective gas price - if baseFee != nil && blockHash != (common.Hash{}) { - // price = min(tip, gasFeeCap - baseFee) + baseFee - price := math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap()) - result.GasPrice = (*hexutil.Big)(price) - } else { - result.GasPrice = (*hexutil.Big)(tx.GasFeeCap()) - } - } - return result -} - -// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation -func newRPCPendingTransaction(tx *types.Transaction, baseFee *big.Int) *RPCTransaction { - return newRPCTransaction(tx, common.Hash{}, 0, 0, baseFee) -} - -// newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation. -func newRPCTransactionFromBlockIndex(b *evmcore.EvmBlock, index uint64) *RPCTransaction { - txs := b.Transactions - if index >= uint64(len(txs)) { - return nil - } - return newRPCTransaction(txs[index], b.Hash, b.NumberU64(), index, b.BaseFee) -} - -// newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index. -func newRPCRawTransactionFromBlockIndex(b *evmcore.EvmBlock, index uint64) hexutil.Bytes { - txs := b.Transactions - if index >= uint64(len(txs)) { - return nil - } - blob, _ := txs[index].MarshalBinary() - return blob -} - -// newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. -func newRPCTransactionFromBlockHash(b *evmcore.EvmBlock, hash common.Hash) *RPCTransaction { - for idx, tx := range b.Transactions { - if tx.Hash() == hash { - return newRPCTransactionFromBlockIndex(b, uint64(idx)) - } - } - return nil -} - -// accessListResult returns an optional accesslist -// Its the result of the `debug_createAccessList` RPC call. -// It contains an error if the transaction itself failed. -type accessListResult struct { - Accesslist *types.AccessList `json:"accessList"` - Error string `json:"error,omitempty"` - GasUsed hexutil.Uint64 `json:"gasUsed"` -} - -// CreateAccessList creates a EIP-2930 type AccessList for the given transaction. -// Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state. -func (s *PublicBlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { - bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) - if blockNrOrHash != nil { - bNrOrHash = *blockNrOrHash - } - acl, gasUsed, vmerr, err := AccessList(ctx, s.b, bNrOrHash, args) - if err != nil { - return nil, err - } - result := &accessListResult{Accesslist: &acl, GasUsed: hexutil.Uint64(gasUsed)} - if vmerr != nil { - result.Error = vmerr.Error() - } - return result, nil -} - -// AccessList creates an access list for the given transaction. -// If the accesslist creation fails an error is returned. -// If the transaction itself fails, an vmErr is returned. -func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args TransactionArgs) (acl types.AccessList, gasUsed uint64, vmErr error, err error) { - // Retrieve the execution context - db, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if db == nil || err != nil { - return nil, 0, nil, err - } - // If the gas amount is not set, extract this as it will depend on access - // lists and we'll need to reestimate every time - nogas := args.Gas == nil - - // Ensure any missing fields are filled, extract the recipient and input data - if err := args.setDefaults(ctx, b); err != nil { - return nil, 0, nil, err - } - var to common.Address - if args.To != nil { - to = *args.To - } else { - to = crypto.CreateAddress(args.from(), uint64(*args.Nonce)) - } - // Retrieve the precompiles since they don't need to be added to the access list - precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number)) - - // Create an initial tracer - prevTracer := vm.NewAccessListTracer(nil, args.from(), to, precompiles) - if args.AccessList != nil { - prevTracer = vm.NewAccessListTracer(*args.AccessList, args.from(), to, precompiles) - } - for { - // Retrieve the current access list to expand - accessList := prevTracer.AccessList() - log.Trace("Creating access list", "input", accessList) - - // If no gas amount was specified, each unique access list needs it's own - // gas calculation. This is quite expensive, but we need to be accurate - // and it's convered by the sender only anyway. - if nogas { - args.Gas = nil - if err := args.setDefaults(ctx, b); err != nil { - return nil, 0, nil, err // shouldn't happen, just in case - } - } - // Copy the original db so we don't modify it - statedb := db.Copy() - // Set the accesslist to the last al - args.AccessList = &accessList - msg, err := args.ToMessage(b.RPCGasCap(), header.BaseFee) - if err != nil { - return nil, 0, nil, err - } - - // Apply the transaction with the access list tracer - tracer := vm.NewAccessListTracer(accessList, args.from(), to, precompiles) - config := opera.DefaultVMConfig - config.Tracer = tracer - config.Debug = true - config.NoBaseFee = true - vmenv, _, err := b.GetEVM(ctx, msg, statedb, header, &config) - if err != nil { - return nil, 0, nil, err - } - res, err := evmcore.ApplyMessage(vmenv, msg, new(evmcore.GasPool).AddGas(msg.Gas())) - if err != nil { - return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err) - } - if tracer.Equal(prevTracer) { - return accessList, res.UsedGas, res.Err, nil - } - prevTracer = tracer - } -} - -// PublicTransactionPoolAPI exposes methods for the RPC interface -type PublicTransactionPoolAPI struct { - b Backend - nonceLock *AddrLocker - signer types.Signer -} - -// NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool. -func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI { - // The signer used by the API should always be the 'latest' known one because we expect - // signers to be backwards-compatible with old transactions. - signer := gsignercache.Wrap(types.LatestSignerForChainID(b.ChainConfig().ChainID)) - return &PublicTransactionPoolAPI{b, nonceLock, signer} -} - -// GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. -func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { - if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { - n := hexutil.Uint(len(block.Transactions)) - return &n - } - return nil -} - -// GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. -func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { - if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { - n := hexutil.Uint(len(block.Transactions)) - return &n - } - return nil -} - -// GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. -func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { - if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { - return newRPCTransactionFromBlockIndex(block, uint64(index)) - } - return nil -} - -// GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. -func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { - if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { - return newRPCTransactionFromBlockIndex(block, uint64(index)) - } - return nil -} - -// GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. -func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { - if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { - return newRPCRawTransactionFromBlockIndex(block, uint64(index)) - } - return nil -} - -// GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. -func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { - if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { - return newRPCRawTransactionFromBlockIndex(block, uint64(index)) - } - return nil -} - -// GetTransactionCount returns the number of transactions the given address has sent for the given block number -func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { - // Ask transaction pool for the nonce which includes pending transactions - if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { - nonce, err := s.b.GetPoolNonce(ctx, address) - if err != nil { - return nil, err - } - return (*hexutil.Uint64)(&nonce), nil - } - // Resolve block number and use its state to ask for the nonce - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { - return nil, err - } - nonce := state.GetNonce(address) - return (*hexutil.Uint64)(&nonce), state.Error() -} - -// GetTransactionByHash returns the transaction for the given hash -func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) { - // Try to return an already finalized transaction - tx, blockNumber, index, err := s.b.GetTransaction(ctx, hash) - if err != nil { - return nil, err - } - if tx != nil { - header, err := s.b.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber)) - if header == nil || err != nil { - return nil, err - } - return newRPCTransaction(tx, header.Hash, blockNumber, index, header.BaseFee), nil - } - // No finalized transaction, try to retrieve it from the pool - if tx := s.b.GetPoolTransaction(hash); tx != nil { - return newRPCPendingTransaction(tx, s.b.MinGasPrice()), nil - } - - // Transaction unknown, return as such - return nil, nil -} - -// GetRawTransactionByHash returns the bytes of the transaction for the given hash. -func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { - // Retrieve a finalized transaction, or a pooled otherwise - tx, _, _, err := s.b.GetTransaction(ctx, hash) - if err != nil { - return nil, err - } - if tx == nil { - if tx = s.b.GetPoolTransaction(hash); tx == nil { - // Transaction not found anywhere, abort - return nil, nil - } - } - // Serialize to RLP and return - return tx.MarshalBinary() -} - -// GetTransactionReceipt returns the transaction receipt for the given transaction hash. -func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { - tx, blockNumber, index, err := s.b.GetTransaction(ctx, hash) - if tx == nil || err != nil { - return nil, err - } - header, err := s.b.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber)) // retrieve header to get block hash - if header == nil || err != nil { - return nil, err - } - receipts, err := s.b.GetReceiptsByNumber(ctx, rpc.BlockNumber(blockNumber)) - if receipts == nil || err != nil { - return nil, err - } - if receipts.Len() <= int(index) { - return nil, nil - } - receipt := receipts[index] - - for _, l := range receipt.Logs { - l.TxHash = hash - l.BlockHash = header.Hash - l.BlockNumber = blockNumber - } - - // Derive the sender. - bigblock := new(big.Int).SetUint64(blockNumber) - signer := gsignercache.Wrap(types.MakeSigner(s.b.ChainConfig(), bigblock)) - from, _ := internaltx.Sender(signer, tx) - - fields := map[string]interface{}{ - "blockHash": header.Hash, - "blockNumber": hexutil.Uint64(blockNumber), - "transactionHash": hash, - "transactionIndex": hexutil.Uint64(index), - "from": from, - "to": tx.To(), - "gasUsed": hexutil.Uint64(receipt.GasUsed), - "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), - "contractAddress": nil, - "logs": receipt.Logs, - "logsBloom": &receipt.Bloom, - "type": hexutil.Uint(tx.Type()), - } - // Assign the effective gas price paid - if header.BaseFee == nil { - fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64()) - } else { - gasPrice := new(big.Int).Add(header.BaseFee, tx.EffectiveGasTipValue(header.BaseFee)) - fields["effectiveGasPrice"] = hexutil.Uint64(gasPrice.Uint64()) - } - // Assign receipt status or post state. - if len(receipt.PostState) > 0 { - fields["root"] = hexutil.Bytes(receipt.PostState) - } else { - fields["status"] = hexutil.Uint(receipt.Status) - } - if receipt.Logs == nil { - fields["logs"] = [][]*types.Log{} - } - // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation - if tx.To() == nil { - fields["contractAddress"] = receipt.ContractAddress - } - return fields, nil -} - -// sign is a helper function that signs a transaction with the private key of the given address. -func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { - // Look up the wallet containing the requested signer - account := accounts.Account{Address: addr} - - wallet, err := s.b.AccountManager().Find(account) - if err != nil { - return nil, err - } - // Request the wallet to sign the transaction - return wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) -} - -// SubmitTransaction is a helper function that submits tx to txPool and logs a message. -func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { - // If the transaction fee cap is already specified, ensure the - // fee of the given transaction is _reasonable_. - if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil { - return common.Hash{}, err - } - if !b.UnprotectedAllowed() && !tx.Protected() { - // Ensure only eip155 signed transactions are submitted if EIP155Required is set. - return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC") - } - if err := b.SendTx(ctx, tx); err != nil { - return common.Hash{}, err - } // Print a log with full tx details for manual investigations and interventions - signer := gsignercache.Wrap(types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number)) - from, err := types.Sender(signer, tx) - if err != nil { - return common.Hash{}, err - } - - if tx.To() == nil { - addr := crypto.CreateAddress(from, tx.Nonce()) - log.Info("Submitted contract creation", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "contract", addr.Hex(), "value", tx.Value()) - } else { - log.Info("Submitted transaction", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "recipient", tx.To(), "value", tx.Value()) - } - return tx.Hash(), nil -} - -// SendTransaction creates a transaction for the given argument, sign it and submit it to the -// transaction pool. -func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args TransactionArgs) (common.Hash, error) { - // Look up the wallet containing the requested signer - account := accounts.Account{Address: args.from()} - - wallet, err := s.b.AccountManager().Find(account) - if err != nil { - return common.Hash{}, err - } - - if args.Nonce == nil { - // Hold the addresse's mutex around signing to prevent concurrent assignment of - // the same nonce to multiple accounts. - s.nonceLock.LockAddr(args.from()) - defer s.nonceLock.UnlockAddr(args.from()) - } - - // Set some sanity defaults and terminate on failure - if err := args.setDefaults(ctx, s.b); err != nil { - return common.Hash{}, err - } - // Assemble the transaction and sign with the wallet - tx := args.toTransaction() - - signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) - if err != nil { - return common.Hash{}, err - } - return SubmitTransaction(ctx, s.b, signed) -} - -// FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields) -// on a given unsigned transaction, and returns it to the caller for further -// processing (signing + broadcast). -func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { - // Set some sanity defaults and terminate on failure - if err := args.setDefaults(ctx, s.b); err != nil { - return nil, err - } - // Assemble the transaction and obtain rlp - tx := args.toTransaction() - data, err := tx.MarshalBinary() - if err != nil { - return nil, err - } - return &SignTransactionResult{data, tx}, nil -} - -// SendRawTransaction will add the signed transaction to the transaction pool. -// The sender is responsible for signing the transaction and using the correct nonce. -func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { - tx := new(types.Transaction) - if err := tx.UnmarshalBinary(encodedTx); err != nil { - return common.Hash{}, err - } - return SubmitTransaction(ctx, s.b, tx) -} - -// Sign calculates an ECDSA signature for: -// keccack256("\x19Ethereum Signed Message:\n" + len(message) + message). -// -// Note, the produced signature conforms to the secp256k1 curve R, S and V values, -// where the V value will be 27 or 28 for legacy reasons. -// -// The account associated with addr must be unlocked. -// -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign -func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { - // Look up the wallet containing the requested signer - account := accounts.Account{Address: addr} - - wallet, err := s.b.AccountManager().Find(account) - if err != nil { - return nil, err - } - // Sign the requested hash with the wallet - signature, err := wallet.SignText(account, data) - if err == nil { - signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper - } - return signature, err -} - -// SignTransactionResult represents a RLP encoded signed transaction. -type SignTransactionResult struct { - Raw hexutil.Bytes `json:"raw"` - Tx *types.Transaction `json:"tx"` -} - -// SignTransaction will sign the given transaction with the from account. -// The node needs to have the private key of the account corresponding with -// the given from address and it needs to be unlocked. -func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { - if args.Gas == nil { - return nil, fmt.Errorf("gas not specified") - } - if args.GasPrice == nil && (args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil) { - return nil, fmt.Errorf("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas") - } - if args.Nonce == nil { - return nil, fmt.Errorf("nonce not specified") - } - if err := args.setDefaults(ctx, s.b); err != nil { - return nil, err - } - // Before actually sign the transaction, ensure the transaction fee is reasonable. - tx := args.toTransaction() - if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil { - return nil, err - } - signed, err := s.sign(args.from(), tx) - if err != nil { - return nil, err - } - data, err := signed.MarshalBinary() - if err != nil { - return nil, err - } - return &SignTransactionResult{data, signed}, nil -} - -// PendingTransactions returns the transactions that are in the transaction pool -// and have a from address that is one of the accounts this node manages. -func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) { - pending, err := s.b.GetPoolTransactions() - if err != nil { - return nil, err - } - accounts := make(map[common.Address]struct{}) - for _, wallet := range s.b.AccountManager().Wallets() { - for _, account := range wallet.Accounts() { - accounts[account.Address] = struct{}{} - } - } - transactions := make([]*RPCTransaction, 0, len(pending)) - for _, tx := range pending { - from, _ := internaltx.Sender(s.signer, tx) - if _, exists := accounts[from]; exists { - transactions = append(transactions, newRPCPendingTransaction(tx, s.b.MinGasPrice())) - } - } - return transactions, nil -} - -// Resend accepts an existing transaction and a new gas price and limit. It will remove -// the given transaction from the pool and reinsert it with the new gas price and limit. -func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { - if sendArgs.Nonce == nil { - return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") - } - if err := sendArgs.setDefaults(ctx, s.b); err != nil { - return common.Hash{}, err - } - matchTx := sendArgs.toTransaction() - - // Before replacing the old transaction, ensure the _new_ transaction fee is reasonable. - var price = matchTx.GasPrice() - if gasPrice != nil { - price = gasPrice.ToInt() - } - var gas = matchTx.Gas() - if gasLimit != nil { - gas = uint64(*gasLimit) - } - if err := checkTxFee(price, gas, s.b.RPCTxFeeCap()); err != nil { - return common.Hash{}, err - } - // Iterate the pending list for replacement - pending, err := s.b.GetPoolTransactions() - if err != nil { - return common.Hash{}, err - } - - for _, p := range pending { - wantSigHash := s.signer.Hash(matchTx) - pFrom, err := types.Sender(s.signer, p) - if err == nil && pFrom == sendArgs.from() && s.signer.Hash(p) == wantSigHash { - // Match. Re-sign and send the transaction. - if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 { - sendArgs.GasPrice = gasPrice - } - if gasLimit != nil && *gasLimit != 0 { - sendArgs.Gas = gasLimit - } - signedTx, err := s.sign(sendArgs.from(), sendArgs.toTransaction()) - if err != nil { - return common.Hash{}, err - } - if err = s.b.SendTx(ctx, signedTx); err != nil { - return common.Hash{}, err - } - return signedTx.Hash(), nil - } - } - return common.Hash{}, fmt.Errorf("transaction %#x not found", matchTx.Hash()) -} - -// PublicDebugAPI is the collection of Ethereum APIs exposed over the public -// debugging endpoint. -type PublicDebugAPI struct { - b Backend -} - -// NewPublicDebugAPI creates a new API definition for the public debug methods -// of the Ethereum service. -func NewPublicDebugAPI(b Backend) *PublicDebugAPI { - return &PublicDebugAPI{b: b} -} - -// GetBlockRlp retrieves the RLP encoded for of a single block. -func (api *PublicDebugAPI) GetBlockRlp(ctx context.Context, number uint64) (string, error) { - block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) - if block == nil { - return "", fmt.Errorf("block #%d not found", number) - } - encoded, err := rlp.EncodeToBytes(block) - if err != nil { - return "", err - } - return fmt.Sprintf("%x", encoded), nil -} - -// TestSignCliqueBlock fetches the given block number, and attempts to sign it as a clique header with the -// given address, returning the address of the recovered signature -// -// This is a temporary method to debug the externalsigner integration, -func (api *PublicDebugAPI) TestSignCliqueBlock(ctx context.Context, address common.Address, number uint64) (common.Address, error) { - return common.Address{}, errors.New("Clique isn't supported") -} - -// PrintBlock retrieves a block and returns its pretty printed form. -func (api *PublicDebugAPI) PrintBlock(ctx context.Context, number uint64) (string, error) { - block, err := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) - if err != nil { - return "", err - } - if block == nil { - return "", fmt.Errorf("block #%d not found", number) - } - return spew.Sdump(block), nil -} - -// SeedHash retrieves the seed hash of a block. -func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string, error) { - block, err := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) - if err != nil { - return "", err - } - if block == nil { - return "", fmt.Errorf("block #%d not found", number) - } - return fmt.Sprintf("0x%x", ethash.SeedHash(number)), nil -} - -// BlocksTransactionTimes returns the map time => number of transactions -// This data may be used to draw a histogram to calculate a peak TPS of a range of blocks -func (api *PublicDebugAPI) BlocksTransactionTimes(ctx context.Context, untilBlock rpc.BlockNumber, maxBlocks hexutil.Uint64) (map[hexutil.Uint64]hexutil.Uint, error) { - - until, err := api.b.HeaderByNumber(ctx, untilBlock) - if until == nil || err != nil { - return nil, err - } - untilN := until.Number.Uint64() - times := map[hexutil.Uint64]hexutil.Uint{} - for i := untilN; i >= 1 && i+uint64(maxBlocks) > untilN; i-- { - b, err := api.b.BlockByNumber(ctx, rpc.BlockNumber(i)) - if b == nil || err != nil { - return nil, err - } - if b.Transactions.Len() == 0 { - continue - } - times[hexutil.Uint64(b.Time)] += hexutil.Uint(b.Transactions.Len()) - } - - return times, nil -} - -// PrivateDebugAPI is the collection of Ethereum APIs exposed over the private -// debugging endpoint. -type PrivateDebugAPI struct { - b Backend -} - -// NewPrivateDebugAPI creates a new API definition for the private debug methods -// of the Ethereum service. -func NewPrivateDebugAPI(b Backend) *PrivateDebugAPI { - return &PrivateDebugAPI{b: b} -} - -// ChaindbProperty returns leveldb properties of the key-value database. -func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { - if property == "" { - property = "stats" - } - return api.b.ChainDb().Stat(property) -} - -// ChaindbCompact flattens the entire key-value database into a single level, -// removing all unused slots and merging all keys. -func (api *PrivateDebugAPI) ChaindbCompact() error { - if err := compactdb.Compact(ethdb2kvdb.Wrap(api.b.ChainDb()), "EVM", 64*opt.GiB); err != nil { - log.Error("Database compaction failed", "err", err) - return err - } - return nil -} - -// SetHead rewinds the head of the blockchain to a previous block. -func (api *PrivateDebugAPI) SetHead(number hexutil.Uint64) error { - return errors.New("lachesis cannot rewind blocks due to the BFT algorithm") -} - -// PublicNetAPI offers network related RPC methods -type PublicNetAPI struct { - net *p2p.Server - networkVersion uint64 -} - -// NewPublicNetAPI creates a new net API instance. -func NewPublicNetAPI(net *p2p.Server, networkVersion uint64) *PublicNetAPI { - return &PublicNetAPI{net, networkVersion} -} - -// Listening returns an indication if the node is listening for network connections. -func (s *PublicNetAPI) Listening() bool { - return true // always listening -} - -// PeerCount returns the number of connected peers -func (s *PublicNetAPI) PeerCount() hexutil.Uint { - return hexutil.Uint(s.net.PeerCount()) -} - -// Version returns the current ethereum protocol version. -func (s *PublicNetAPI) Version() string { - return fmt.Sprintf("%d", s.networkVersion) -} - -// checkTxFee is an internal function used to check whether the fee of -// the given transaction is _reasonable_(under the cap). -func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error { - // Short circuit if there is no cap for transaction fee at all. - if cap == 0 { - return nil - } - feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gas))), new(big.Float).SetInt(big.NewInt(params.Ether))) - feeFloat, _ := feeEth.Float64() - if feeFloat > cap { - return fmt.Errorf("tx fee (%.2f FTM) exceeds the configured cap (%.2f FTM)", feeFloat, cap) - } - return nil -} - -// toHexSlice creates a slice of hex-strings based on []byte. -func toHexSlice(b [][]byte) []string { - r := make([]string, len(b)) - for i := range b { - r[i] = hexutil.Encode(b[i]) - } - return r -} diff --git a/evm/go-x1/ethapi/backend.go b/evm/go-x1/ethapi/backend.go deleted file mode 100644 index d2e9914..0000000 --- a/evm/go-x1/ethapi/backend.go +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package ethapi implements the general Ethereum API functions. -package ethapi - -import ( - "context" - "math/big" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/ethdb" - notify "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rpc" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" -) - -// PeerProgress is synchronization status of a peer -type PeerProgress struct { - CurrentEpoch idx.Epoch - CurrentBlock idx.Block - CurrentBlockHash hash.Event - CurrentBlockTime inter.Timestamp - HighestBlock idx.Block - HighestEpoch idx.Epoch -} - -// Backend interface provides the common API services (that are provided by -// both full and light clients) with access to necessary functions. -type Backend interface { - // General Ethereum API - Progress() PeerProgress - SuggestGasTipCap(ctx context.Context, certainty uint64) *big.Int - EffectiveMinGasPrice(ctx context.Context) *big.Int - ChainDb() ethdb.Database - AccountManager() *accounts.Manager - ExtRPCEnabled() bool - RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection - RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection - RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs - UnprotectedAllowed() bool // allows only for EIP155 transactions. - CalcBlockExtApi() bool - - // Blockchain API - HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*evmcore.EvmHeader, error) - HeaderByHash(ctx context.Context, hash common.Hash) (*evmcore.EvmHeader, error) - BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*evmcore.EvmBlock, error) - StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *evmcore.EvmHeader, error) - ResolveRpcBlockNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (idx.Block, error) - BlockByHash(ctx context.Context, hash common.Hash) (*evmcore.EvmBlock, error) - GetReceiptsByNumber(ctx context.Context, number rpc.BlockNumber) (types.Receipts, error) - GetTd(hash common.Hash) *big.Int - GetEVM(ctx context.Context, msg evmcore.Message, state *state.StateDB, header *evmcore.EvmHeader, vmConfig *vm.Config) (*vm.EVM, func() error, error) - MinGasPrice() *big.Int - MaxGasLimit() uint64 - - // Transaction pool API - SendTx(ctx context.Context, signedTx *types.Transaction) error - GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, uint64, uint64, error) - GetPoolTransactions() (types.Transactions, error) - GetPoolTransaction(txHash common.Hash) *types.Transaction - GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) - Stats() (pending int, queued int) - TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) - TxPoolContentFrom(addr common.Address) (types.Transactions, types.Transactions) - SubscribeNewTxsNotify(chan<- evmcore.NewTxsNotify) notify.Subscription - - ChainConfig() *params.ChainConfig - CurrentBlock() *evmcore.EvmBlock - - // Lachesis DAG API - GetEventPayload(ctx context.Context, shortEventID string) (*inter.EventPayload, error) - GetEvent(ctx context.Context, shortEventID string) (*inter.Event, error) - GetHeads(ctx context.Context, epoch rpc.BlockNumber) (hash.Events, error) - CurrentEpoch(ctx context.Context) idx.Epoch - SealedEpochTiming(ctx context.Context) (start inter.Timestamp, end inter.Timestamp) - - // Lachesis aBFT API - GetEpochBlockState(ctx context.Context, epoch rpc.BlockNumber) (*iblockproc.BlockState, *iblockproc.EpochState, error) - GetDowntime(ctx context.Context, vid idx.ValidatorID) (idx.Block, inter.Timestamp, error) - GetUptime(ctx context.Context, vid idx.ValidatorID) (*big.Int, error) - GetOriginatedFee(ctx context.Context, vid idx.ValidatorID) (*big.Int, error) -} - -func GetAPIs(apiBackend Backend) []rpc.API { - nonceLock := new(AddrLocker) - orig := []rpc.API{ - { - Namespace: "eth", - Version: "1.0", - Service: NewPublicEthereumAPI(apiBackend), - Public: true, - }, { - Namespace: "eth", - Version: "1.0", - Service: NewPublicBlockChainAPI(apiBackend), - Public: true, - }, { - Namespace: "dag", - Version: "1.0", - Service: NewPublicDAGChainAPI(apiBackend), - Public: true, - }, { - Namespace: "eth", - Version: "1.0", - Service: NewPublicTransactionPoolAPI(apiBackend, nonceLock), - Public: true, - }, { - Namespace: "txpool", - Version: "1.0", - Service: NewPublicTxPoolAPI(apiBackend), - Public: true, - }, { - Namespace: "debug", - Version: "1.0", - Service: NewPublicDebugAPI(apiBackend), - Public: true, - }, { - Namespace: "debug", - Version: "1.0", - Service: NewPrivateDebugAPI(apiBackend), - }, { - Namespace: "eth", - Version: "1.0", - Service: NewPublicAccountAPI(apiBackend.AccountManager()), - Public: true, - }, { - Namespace: "personal", - Version: "1.0", - Service: NewPrivateAccountAPI(apiBackend, nonceLock), - Public: false, - }, { - Namespace: "abft", - Version: "1.0", - Service: NewPublicAbftAPI(apiBackend), - Public: true, - }, - } - - // NOTE: eth-namespace is doubled as ftm-namespace for branding purpose - double := []rpc.API{ - { - Namespace: "ftm", - Version: "1.0", - Service: NewPublicEthereumAPI(apiBackend), - Public: true, - }, { - Namespace: "ftm", - Version: "1.0", - Service: NewPublicBlockChainAPI(apiBackend), - Public: true, - }, { - Namespace: "ftm", - Version: "1.0", - Service: NewPublicTransactionPoolAPI(apiBackend, nonceLock), - Public: true, - }, { - Namespace: "ftm", - Version: "1.0", - Service: NewPublicAccountAPI(apiBackend.AccountManager()), - Public: true, - }, - } - - return append(orig, double...) -} diff --git a/evm/go-x1/ethapi/dag_api.go b/evm/go-x1/ethapi/dag_api.go deleted file mode 100644 index 93e5e9e..0000000 --- a/evm/go-x1/ethapi/dag_api.go +++ /dev/null @@ -1,81 +0,0 @@ -package ethapi - -import ( - "context" - "errors" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rpc" - - "github.com/Fantom-foundation/go-opera/inter" -) - -// PublicDAGChainAPI provides an API to access the directed acyclic graph chain. -// It offers only methods that operate on public data that is freely available to anyone. -type PublicDAGChainAPI struct { - b Backend -} - -// NewPublicDAGChainAPI creates a new DAG chain API. -func NewPublicDAGChainAPI(b Backend) *PublicDAGChainAPI { - return &PublicDAGChainAPI{b} -} - -// GetEvent returns the Lachesis event header by hash or short ID. -func (s *PublicDAGChainAPI) GetEvent(ctx context.Context, shortEventID string) (map[string]interface{}, error) { - header, err := s.b.GetEvent(ctx, shortEventID) - if err != nil { - return nil, err - } - if header == nil { - return nil, fmt.Errorf("event %s not found", shortEventID) - } - return inter.RPCMarshalEvent(header), nil -} - -// GetEventPayload returns Lachesis event by hash or short ID. -func (s *PublicDAGChainAPI) GetEventPayload(ctx context.Context, shortEventID string, inclTx bool) (map[string]interface{}, error) { - event, err := s.b.GetEventPayload(ctx, shortEventID) - if err != nil { - return nil, err - } - if event == nil { - return nil, fmt.Errorf("event %s not found", shortEventID) - } - return inter.RPCMarshalEventPayload(event, inclTx, false) -} - -// GetHeads returns IDs of all the epoch events with no descendants. -// * When epoch is -2 the heads for latest epoch are returned. -// * When epoch is -1 the heads for latest sealed epoch are returned. -func (s *PublicDAGChainAPI) GetHeads(ctx context.Context, epoch rpc.BlockNumber) ([]hexutil.Bytes, error) { - res, err := s.b.GetHeads(ctx, epoch) - - if err != nil { - return nil, err - } - - return inter.EventIDsToHex(res), nil -} - -// GetEpochStats returns epoch statistics. -// * When epoch is -2 the statistics for latest epoch is returned. -// * When epoch is -1 the statistics for latest sealed epoch is returned. -func (s *PublicBlockChainAPI) GetEpochStats(ctx context.Context, requestedEpoch rpc.BlockNumber) (map[string]interface{}, error) { - log.Warn("GetEpochStats API call is deprecated. Consider retrieving data from SFC v3 contract.") - if requestedEpoch != rpc.LatestBlockNumber && requestedEpoch != rpc.BlockNumber(s.b.CurrentEpoch(ctx))-1 { - return nil, errors.New("getEpochStats API call doesn't support retrieving previous sealed epochs") - } - start, end := s.b.SealedEpochTiming(ctx) - return map[string]interface{}{ - "epoch": hexutil.Uint64(s.b.CurrentEpoch(ctx) - 1), - "start": hexutil.Uint64(start), - "end": hexutil.Uint64(end), - "totalFee": (*hexutil.Big)(new(big.Int)), - "totalBaseRewardWeight": (*hexutil.Big)(new(big.Int)), - "totalTxRewardWeight": (*hexutil.Big)(new(big.Int)), - }, nil -} diff --git a/evm/go-x1/ethapi/transaction_args.go b/evm/go-x1/ethapi/transaction_args.go deleted file mode 100644 index 42363f2..0000000 --- a/evm/go-x1/ethapi/transaction_args.go +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package ethapi - -import ( - "bytes" - "context" - "errors" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rpc" - - "github.com/Fantom-foundation/go-opera/gossip/gasprice" -) - -// TransactionArgs represents the arguments to construct a new transaction -// or a message call. -type TransactionArgs struct { - From *common.Address `json:"from"` - To *common.Address `json:"to"` - Gas *hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` - MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` - Value *hexutil.Big `json:"value"` - Nonce *hexutil.Uint64 `json:"nonce"` - - // We accept "data" and "input" for backwards-compatibility reasons. - // "input" is the newer name and should be preferred by clients. - // Issue detail: https://github.com/ethereum/go-ethereum/issues/15628 - Data *hexutil.Bytes `json:"data"` - Input *hexutil.Bytes `json:"input"` - - // Introduced by AccessListTxType transaction. - AccessList *types.AccessList `json:"accessList,omitempty"` - ChainID *hexutil.Big `json:"chainId,omitempty"` -} - -// from retrieves the transaction sender address. -func (arg *TransactionArgs) from() common.Address { - if arg.From == nil { - return common.Address{} - } - return *arg.From -} - -// data retrieves the transaction calldata. Input field is preferred. -func (arg *TransactionArgs) data() []byte { - if arg.Input != nil { - return *arg.Input - } - if arg.Data != nil { - return *arg.Data - } - return nil -} - -// setDefaults fills in default values for unspecified tx fields. -func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error { - if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { - return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") - } - // After london, default to 1559 unless gasPrice is set - head := b.CurrentBlock().Header() - // If user specifies both maxPriorityfee and maxFee, then we do not - // need to consult the chain for defaults. It's definitely a London tx. - if args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil { - // In this clause, user left some fields unspecified. - if b.ChainConfig().IsLondon(head.Number) && args.GasPrice == nil { - if args.MaxPriorityFeePerGas == nil { - tip := b.SuggestGasTipCap(ctx, gasprice.AsDefaultCertainty) - args.MaxPriorityFeePerGas = (*hexutil.Big)(tip) - } - if args.MaxFeePerGas == nil { - gasFeeCap := new(big.Int).Add( - (*big.Int)(args.MaxPriorityFeePerGas), - b.MinGasPrice(), - ) - args.MaxFeePerGas = (*hexutil.Big)(gasFeeCap) - } - if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 { - return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas) - } - } else { - if args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil { - return errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet") - } - if args.GasPrice == nil { - price := b.SuggestGasTipCap(ctx, gasprice.AsDefaultCertainty) - price.Add(price, b.MinGasPrice()) - args.GasPrice = (*hexutil.Big)(price) - } - } - } else { - // Both maxPriorityfee and maxFee set by caller. Sanity-check their internal relation - if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 { - return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas) - } - } - if args.Value == nil { - args.Value = new(hexutil.Big) - } - if args.Nonce == nil { - nonce, err := b.GetPoolNonce(ctx, args.from()) - if err != nil { - return err - } - args.Nonce = (*hexutil.Uint64)(&nonce) - } - if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { - return errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`) - } - if args.To == nil && len(args.data()) == 0 { - return errors.New(`contract creation without any data provided`) - } - // Estimate the gas usage if necessary. - if args.Gas == nil { - // These fields are immutable during the estimation, safe to - // pass the pointer directly. - callArgs := TransactionArgs{ - From: args.From, - To: args.To, - GasPrice: args.GasPrice, - MaxFeePerGas: args.MaxFeePerGas, - MaxPriorityFeePerGas: args.MaxPriorityFeePerGas, - Value: args.Value, - Data: args.Data, - AccessList: args.AccessList, - } - pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) - estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, b.RPCGasCap()) - if err != nil { - return err - } - args.Gas = &estimated - log.Trace("Estimate gas usage automatically", "gas", args.Gas) - } - if args.ChainID == nil { - id := (*hexutil.Big)(b.ChainConfig().ChainID) - args.ChainID = id - } - return nil -} - -// ToMessage converts the transaction arguments to the Message type used by the -// core evm. This method is used in calls and traces that do not require a real -// live transaction. -func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (types.Message, error) { - // Reject invalid combinations of pre- and post-1559 fee styles - if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { - return types.Message{}, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") - } - // Set sender address or use zero address if none specified. - addr := args.from() - - // Set default gas & gas price if none were set - gas := globalGasCap - if gas == 0 { - gas = uint64(math.MaxUint64 / 2) - } - if args.Gas != nil { - gas = uint64(*args.Gas) - } - if globalGasCap != 0 && globalGasCap < gas { - log.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap) - gas = globalGasCap - } - var ( - gasPrice *big.Int - gasFeeCap *big.Int - gasTipCap *big.Int - ) - if baseFee == nil { - // If there's no basefee, then it must be a non-1559 execution - gasPrice = new(big.Int) - if args.GasPrice != nil { - gasPrice = args.GasPrice.ToInt() - } - gasFeeCap, gasTipCap = gasPrice, gasPrice - } else { - // A basefee is provided, necessitating 1559-type execution - if args.GasPrice != nil { - // User specified the legacy gas field, convert to 1559 gas typing - gasPrice = args.GasPrice.ToInt() - gasFeeCap, gasTipCap = gasPrice, gasPrice - } else { - // User specified 1559 gas feilds (or none), use those - gasFeeCap = new(big.Int) - if args.MaxFeePerGas != nil { - gasFeeCap = args.MaxFeePerGas.ToInt() - } - gasTipCap = new(big.Int) - if args.MaxPriorityFeePerGas != nil { - gasTipCap = args.MaxPriorityFeePerGas.ToInt() - } - // Backfill the legacy gasPrice for EVM execution, unless we're all zeroes - gasPrice = new(big.Int) - if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 { - gasPrice = math.BigMin(new(big.Int).Add(gasTipCap, baseFee), gasFeeCap) - } - } - } - value := new(big.Int) - if args.Value != nil { - value = args.Value.ToInt() - } - data := args.data() - var accessList types.AccessList - if args.AccessList != nil { - accessList = *args.AccessList - } - msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, true) - return msg, nil -} - -// toTransaction converts the arguments to a transaction. -// This assumes that setDefaults has been called. -func (args *TransactionArgs) toTransaction() *types.Transaction { - var data types.TxData - switch { - case args.MaxFeePerGas != nil: - al := types.AccessList{} - if args.AccessList != nil { - al = *args.AccessList - } - data = &types.DynamicFeeTx{ - To: args.To, - ChainID: (*big.Int)(args.ChainID), - Nonce: uint64(*args.Nonce), - Gas: uint64(*args.Gas), - GasFeeCap: (*big.Int)(args.MaxFeePerGas), - GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas), - Value: (*big.Int)(args.Value), - Data: args.data(), - AccessList: al, - } - case args.AccessList != nil: - data = &types.AccessListTx{ - To: args.To, - ChainID: (*big.Int)(args.ChainID), - Nonce: uint64(*args.Nonce), - Gas: uint64(*args.Gas), - GasPrice: (*big.Int)(args.GasPrice), - Value: (*big.Int)(args.Value), - Data: args.data(), - AccessList: *args.AccessList, - } - default: - data = &types.LegacyTx{ - To: args.To, - Nonce: uint64(*args.Nonce), - Gas: uint64(*args.Gas), - GasPrice: (*big.Int)(args.GasPrice), - Value: (*big.Int)(args.Value), - Data: args.data(), - } - } - return types.NewTx(data) -} - -// ToTransaction converts the arguments to a transaction. -// This assumes that setDefaults has been called. -func (args *TransactionArgs) ToTransaction() *types.Transaction { - return args.toTransaction() -} diff --git a/evm/go-x1/eventcheck/all.go b/evm/go-x1/eventcheck/all.go deleted file mode 100644 index 33b0fac..0000000 --- a/evm/go-x1/eventcheck/all.go +++ /dev/null @@ -1,43 +0,0 @@ -package eventcheck - -import ( - "github.com/Fantom-foundation/go-opera/eventcheck/basiccheck" - "github.com/Fantom-foundation/go-opera/eventcheck/epochcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/gaspowercheck" - "github.com/Fantom-foundation/go-opera/eventcheck/heavycheck" - "github.com/Fantom-foundation/go-opera/eventcheck/parentscheck" - "github.com/Fantom-foundation/go-opera/inter" -) - -// Checkers is collection of all the checkers -type Checkers struct { - Basiccheck *basiccheck.Checker - Epochcheck *epochcheck.Checker - Parentscheck *parentscheck.Checker - Gaspowercheck *gaspowercheck.Checker - Heavycheck *heavycheck.Checker -} - -// Validate runs all the checks except Poset-related -func (v *Checkers) Validate(e inter.EventPayloadI, parents inter.EventIs) error { - if err := v.Basiccheck.Validate(e); err != nil { - return err - } - if err := v.Epochcheck.Validate(e); err != nil { - return err - } - if err := v.Parentscheck.Validate(e, parents); err != nil { - return err - } - var selfParent inter.EventI - if e.SelfParent() != nil { - selfParent = parents[0] - } - if err := v.Gaspowercheck.Validate(e, selfParent); err != nil { - return err - } - if err := v.Heavycheck.ValidateEvent(e); err != nil { - return err - } - return nil -} diff --git a/evm/go-x1/eventcheck/ban.go b/evm/go-x1/eventcheck/ban.go deleted file mode 100644 index 1c4f1bb..0000000 --- a/evm/go-x1/eventcheck/ban.go +++ /dev/null @@ -1,42 +0,0 @@ -package eventcheck - -import ( - "errors" - - base "github.com/Fantom-foundation/lachesis-base/eventcheck" - - "github.com/Fantom-foundation/go-opera/eventcheck/epochcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/heavycheck" -) - -var ( - ErrAlreadyProcessedBVs = errors.New("BVs is processed already") - ErrAlreadyProcessedBR = errors.New("BR is processed already") - ErrAlreadyProcessedEV = errors.New("EV is processed already") - ErrAlreadyProcessedER = errors.New("ER is processed already") - ErrUnknownEpochBVs = heavycheck.ErrUnknownEpochBVs - ErrUnknownEpochEV = heavycheck.ErrUnknownEpochEV - ErrUndecidedBR = errors.New("BR is unprocessable yet") - ErrUndecidedER = errors.New("ER is unprocessable yet") - ErrAlreadyConnectedEvent = base.ErrAlreadyConnectedEvent - ErrSpilledEvent = base.ErrSpilledEvent - ErrDuplicateEvent = base.ErrDuplicateEvent -) - -func IsBan(err error) bool { - if err == epochcheck.ErrNotRelevant || - err == ErrAlreadyConnectedEvent || - err == ErrAlreadyProcessedBVs || - err == ErrAlreadyProcessedBR || - err == ErrAlreadyProcessedEV || - err == ErrAlreadyProcessedER || - err == ErrUnknownEpochBVs || - err == ErrUndecidedBR || - err == ErrUnknownEpochEV || - err == ErrUndecidedER || - err == ErrSpilledEvent || - err == ErrDuplicateEvent { - return false - } - return err != nil -} diff --git a/evm/go-x1/eventcheck/basiccheck/basic_check.go b/evm/go-x1/eventcheck/basiccheck/basic_check.go deleted file mode 100644 index d9de061..0000000 --- a/evm/go-x1/eventcheck/basiccheck/basic_check.go +++ /dev/null @@ -1,306 +0,0 @@ -package basiccheck - -import ( - "errors" - "math" - - base "github.com/Fantom-foundation/lachesis-base/eventcheck/basiccheck" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/inter" -) - -var ( - ErrWrongNetForkID = errors.New("wrong network fork ID") - ErrZeroTime = errors.New("event has zero timestamp") - ErrNegativeValue = errors.New("negative value") - ErrIntrinsicGas = errors.New("intrinsic gas too low") - // ErrTipAboveFeeCap is a sanity error to ensure no one is able to specify a - // transaction with a tip higher than the total fee cap. - ErrTipAboveFeeCap = errors.New("max priority fee per gas higher than max fee per gas") - ErrWrongMP = errors.New("inconsistent misbehaviour proof") - ErrNoCrimeInMP = errors.New("action in misbehaviour proof isn't a criminal offence") - ErrWrongCreatorMP = errors.New("wrong creator in misbehaviour proof") - ErrMPTooLate = errors.New("too old misbehaviour proof") - ErrMalformedMP = errors.New("malformed MP union struct") - FutureBVsEpoch = errors.New("future block votes epoch") - FutureEVEpoch = errors.New("future epoch vote") - MalformedBVs = errors.New("malformed BVs") - MalformedEV = errors.New("malformed EV") - TooManyBVs = errors.New("too many BVs") - EmptyEV = errors.New("empty EV") - EmptyBVs = errors.New("empty BVs") -) - -const ( - MaxBlockVotesPerEvent = 64 - MaxLiableEpochs = 32768 -) - -type Checker struct { - base base.Checker -} - -// New validator which performs checks which don't require anything except event -func New() *Checker { - return &Checker{ - base: base.Checker{}, - } -} - -// validateTx checks whether a transaction is valid according to the consensus -// rules -func validateTx(tx *types.Transaction) error { - // Transactions can't be negative. This may never happen using RLP decoded - // transactions but may occur if you create a transaction using the RPC. - if tx.Value().Sign() < 0 || tx.GasPrice().Sign() < 0 { - return ErrNegativeValue - } - // Ensure the transaction has more gas than the basic tx fee. - intrGas, err := evmcore.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil) - if err != nil { - return err - } - if tx.Gas() < intrGas { - return ErrIntrinsicGas - } - - if tx.GasFeeCapIntCmp(tx.GasTipCap()) < 0 { - return ErrTipAboveFeeCap - } - return nil -} - -func (v *Checker) validateMP(msgEpoch idx.Epoch, mp inter.MisbehaviourProof) error { - count := 0 - if proof := mp.EventsDoublesign; proof != nil { - count++ - if err := v.validateEventLocator(proof.Pair[0].Locator); err != nil { - return err - } - if err := v.validateEventLocator(proof.Pair[1].Locator); err != nil { - return err - } - if proof.Pair[0].Locator.Creator != proof.Pair[1].Locator.Creator { - return ErrWrongCreatorMP - } - if proof.Pair[0].Locator.Epoch != proof.Pair[1].Locator.Epoch { - return ErrNoCrimeInMP - } - if proof.Pair[0].Locator.Seq != proof.Pair[1].Locator.Seq { - return ErrNoCrimeInMP - } - if proof.Pair[0].Locator == proof.Pair[1].Locator { - return ErrNoCrimeInMP - } - if msgEpoch > proof.Pair[0].Locator.Epoch+MaxLiableEpochs { - return ErrMPTooLate - } - } - if proof := mp.BlockVoteDoublesign; proof != nil { - count++ - if err := v.ValidateBVs(proof.Pair[0]); err != nil { - return err - } - if err := v.ValidateBVs(proof.Pair[1]); err != nil { - return err - } - if proof.Pair[0].Signed.Locator.Creator != proof.Pair[1].Signed.Locator.Creator { - return ErrWrongCreatorMP - } - if proof.Block < proof.Pair[0].Val.Start || proof.Block >= proof.Pair[0].Val.Start+idx.Block(len(proof.Pair[0].Val.Votes)) { - return ErrWrongMP - } - if proof.Block < proof.Pair[1].Val.Start || proof.Block >= proof.Pair[1].Val.Start+idx.Block(len(proof.Pair[1].Val.Votes)) { - return ErrWrongMP - } - if proof.GetVote(0) == proof.GetVote(1) && proof.Pair[0].Val.Epoch == proof.Pair[1].Val.Epoch { - return ErrNoCrimeInMP - } - if msgEpoch > proof.Pair[0].Val.Epoch+MaxLiableEpochs || msgEpoch > proof.Pair[1].Val.Epoch+MaxLiableEpochs { - return ErrMPTooLate - } - } - if proof := mp.WrongBlockVote; proof != nil { - count++ - for i, pal := range proof.Pals { - if err := v.ValidateBVs(pal); err != nil { - return err - } - if proof.Block < pal.Val.Start || proof.Block >= pal.Val.Start+idx.Block(len(pal.Val.Votes)) { - return ErrWrongMP - } - if msgEpoch > pal.Val.Epoch+MaxLiableEpochs { - return ErrMPTooLate - } - // see MinAccomplicesForProof - if proof.WrongEpoch { - if i > 0 && pal.Val.Epoch != proof.Pals[i-1].Val.Epoch { - return ErrNoCrimeInMP - } - } else { - if i > 0 && proof.GetVote(i-1) != proof.GetVote(i) { - return ErrNoCrimeInMP - } - } - for _, prev := range proof.Pals[:i] { - if prev.Signed.Locator.Creator == pal.Signed.Locator.Creator { - return ErrWrongCreatorMP - } - } - } - } - if proof := mp.EpochVoteDoublesign; proof != nil { - count++ - if err := v.ValidateEV(proof.Pair[0]); err != nil { - return err - } - if err := v.ValidateEV(proof.Pair[1]); err != nil { - return err - } - if proof.Pair[0].Signed.Locator.Creator != proof.Pair[1].Signed.Locator.Creator { - return ErrWrongCreatorMP - } - if proof.Pair[0].Val.Epoch != proof.Pair[1].Val.Epoch { - return ErrNoCrimeInMP - } - if proof.Pair[0].Val.Vote == proof.Pair[1].Val.Vote { - return ErrNoCrimeInMP - } - if msgEpoch > proof.Pair[0].Val.Epoch+MaxLiableEpochs { - return ErrMPTooLate - } - } - if proof := mp.WrongEpochVote; proof != nil { - count++ - for i, pal := range proof.Pals { - if err := v.ValidateEV(pal); err != nil { - return err - } - if msgEpoch > pal.Val.Epoch+MaxLiableEpochs { - return ErrMPTooLate - } - // see MinAccomplicesForProof - if i > 0 && proof.Pals[i-1].Val != proof.Pals[i].Val { - return ErrNoCrimeInMP - } - for _, prev := range proof.Pals[:i] { - if prev.Signed.Locator.Creator == pal.Signed.Locator.Creator { - return ErrWrongCreatorMP - } - } - } - } - if count != 1 { - return ErrMalformedMP - } - return nil -} - -func (v *Checker) checkTxs(e inter.EventPayloadI) error { - for _, tx := range e.Txs() { - if err := validateTx(tx); err != nil { - return err - } - } - return nil -} - -// Validate event -func (v *Checker) Validate(e inter.EventPayloadI) error { - if e.NetForkID() != 0 { - return ErrWrongNetForkID - } - if err := v.base.Validate(e); err != nil { - return err - } - if e.GasPowerUsed() >= math.MaxInt64-1 || e.GasPowerLeft().Max() >= math.MaxInt64-1 { - return base.ErrHugeValue - } - if e.CreationTime() <= 0 || e.MedianTime() <= 0 { - return ErrZeroTime - } - if err := v.checkTxs(e); err != nil { - return err - } - for _, mp := range e.MisbehaviourProofs() { - if err := v.validateMP(e.Epoch(), mp); err != nil { - return err - } - } - if err := v.validateEV(e.Epoch(), e.EpochVote(), false); err != nil { - return err - } - if err := v.validateBVs(e.Epoch(), e.BlockVotes(), false); err != nil { - return err - } - - return nil -} - -func (v *Checker) validateEventLocator(e inter.EventLocator) error { - if e.NetForkID != 0 { - return ErrWrongNetForkID - } - if e.Seq >= math.MaxInt32-1 || e.Epoch >= math.MaxInt32-1 || - e.Lamport >= math.MaxInt32-1 { - return base.ErrHugeValue - } - return nil -} - -func (v *Checker) validateBVs(eventEpoch idx.Epoch, bvs inter.LlrBlockVotes, greedy bool) error { - if bvs.Epoch > eventEpoch { - return FutureBVsEpoch - } - if bvs.Start >= math.MaxInt64/2 { - return base.ErrHugeValue - } - if bvs.Epoch >= math.MaxInt32-1 { - return base.ErrHugeValue - } - if len(bvs.Votes) > MaxBlockVotesPerEvent { - return TooManyBVs - } - if ((bvs.Start == 0) != (len(bvs.Votes) == 0)) || ((bvs.Start == 0) != (bvs.Epoch == 0)) { - return MalformedBVs - } - - if greedy && bvs.Epoch == 0 { - return EmptyBVs - } - return nil -} - -func (v *Checker) validateEV(eventEpoch idx.Epoch, ev inter.LlrEpochVote, greedy bool) error { - if ev.Epoch > eventEpoch { - return FutureEVEpoch - } - if (ev.Epoch == 0) != (ev.Vote == hash.Zero) { - return MalformedEV - } - if ev.Epoch >= math.MaxInt32-1 { - return base.ErrHugeValue - } - if greedy && ev.Epoch == 0 { - return EmptyEV - } - return nil -} - -func (v *Checker) ValidateBVs(bvs inter.LlrSignedBlockVotes) error { - if err := v.validateEventLocator(bvs.Signed.Locator); err != nil { - return err - } - return v.validateBVs(bvs.Signed.Locator.Epoch, bvs.Val, true) -} - -func (v *Checker) ValidateEV(ev inter.LlrSignedEpochVote) error { - if err := v.validateEventLocator(ev.Signed.Locator); err != nil { - return err - } - return v.validateEV(ev.Signed.Locator.Epoch, ev.Val, true) -} diff --git a/evm/go-x1/eventcheck/bvallcheck/all_check.go b/evm/go-x1/eventcheck/bvallcheck/all_check.go deleted file mode 100644 index 3d0c60b..0000000 --- a/evm/go-x1/eventcheck/bvallcheck/all_check.go +++ /dev/null @@ -1,34 +0,0 @@ -package bvallcheck - -import ( - "github.com/Fantom-foundation/go-opera/inter" -) - -type Checker struct { - HeavyCheck HeavyCheck - LightCheck LightCheck -} - -type LightCheck func(bvs inter.LlrSignedBlockVotes) error - -type HeavyCheck interface { - Enqueue(bvs inter.LlrSignedBlockVotes, checked func(error)) error -} - -type Callback struct { - HeavyCheck HeavyCheck - LightCheck LightCheck -} - -// Enqueue tries to fill gaps the fetcher's future import queue. -func (c *Checker) Enqueue(bvs inter.LlrSignedBlockVotes, checked func(error)) { - // Run light checks right away - err := c.LightCheck(bvs) - if err != nil { - checked(err) - return - } - - // Run heavy check in parallel - _ = c.HeavyCheck.Enqueue(bvs, checked) -} diff --git a/evm/go-x1/eventcheck/epochcheck/epoch_check.go b/evm/go-x1/eventcheck/epochcheck/epoch_check.go deleted file mode 100644 index a4b51d7..0000000 --- a/evm/go-x1/eventcheck/epochcheck/epoch_check.go +++ /dev/null @@ -1,133 +0,0 @@ -package epochcheck - -import ( - "errors" - - base "github.com/Fantom-foundation/lachesis-base/eventcheck/epochcheck" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera" -) - -var ( - ErrTooManyParents = errors.New("event has too many parents") - ErrTooBigGasUsed = errors.New("event uses too much gas power") - ErrWrongGasUsed = errors.New("event has incorrect gas power") - ErrUnderpriced = errors.New("event transaction underpriced") - ErrTooBigExtra = errors.New("event extra data is too large") - ErrWrongVersion = errors.New("event has wrong version") - ErrUnsupportedTxType = errors.New("unsupported tx type") - ErrNotRelevant = base.ErrNotRelevant - ErrAuth = base.ErrAuth -) - -// Reader returns currents epoch and its validators group. -type Reader interface { - base.Reader - GetEpochRules() (opera.Rules, idx.Epoch) -} - -// Checker which require only current epoch info -type Checker struct { - Base *base.Checker - reader Reader -} - -func New(reader Reader) *Checker { - return &Checker{ - Base: base.New(reader), - reader: reader, - } -} - -func CalcGasPowerUsed(e inter.EventPayloadI, rules opera.Rules) uint64 { - txsGas := uint64(0) - for _, tx := range e.Txs() { - txsGas += tx.Gas() - } - - gasCfg := rules.Economy.Gas - - parentsGas := uint64(0) - if idx.Event(len(e.Parents())) > rules.Dag.MaxFreeParents { - parentsGas = uint64(idx.Event(len(e.Parents()))-rules.Dag.MaxFreeParents) * gasCfg.ParentGas - } - extraGas := uint64(len(e.Extra())) * gasCfg.ExtraDataGas - - mpsGas := uint64(len(e.MisbehaviourProofs())) * gasCfg.MisbehaviourProofGas - - bvsGas := uint64(0) - if e.BlockVotes().Start != 0 { - bvsGas = gasCfg.BlockVotesBaseGas + uint64(len(e.BlockVotes().Votes))*gasCfg.BlockVoteGas - } - - ersGas := uint64(0) - if e.EpochVote().Epoch != 0 { - ersGas = gasCfg.EpochVoteGas - } - - return txsGas + parentsGas + extraGas + gasCfg.EventGas + mpsGas + bvsGas + ersGas -} - -func (v *Checker) checkGas(e inter.EventPayloadI, rules opera.Rules) error { - if e.GasPowerUsed() > rules.Economy.Gas.MaxEventGas { - return ErrTooBigGasUsed - } - if e.GasPowerUsed() != CalcGasPowerUsed(e, rules) { - return ErrWrongGasUsed - } - return nil -} - -func CheckTxs(txs types.Transactions, rules opera.Rules) error { - maxType := uint8(0) - if rules.Upgrades.Berlin { - maxType = 1 - } - if rules.Upgrades.London { - maxType = 2 - } - for _, tx := range txs { - if tx.Type() > maxType { - return ErrUnsupportedTxType - } - if tx.GasFeeCapIntCmp(rules.Economy.MinGasPrice) < 0 { - return ErrUnderpriced - } - } - return nil -} - -// Validate event -func (v *Checker) Validate(e inter.EventPayloadI) error { - if err := v.Base.Validate(e); err != nil { - return err - } - rules, epoch := v.reader.GetEpochRules() - // Check epoch of the rules to prevent a race condition - if e.Epoch() != epoch { - return base.ErrNotRelevant - } - if idx.Event(len(e.Parents())) > rules.Dag.MaxParents { - return ErrTooManyParents - } - if uint32(len(e.Extra())) > rules.Dag.MaxExtraData { - return ErrTooBigExtra - } - if err := v.checkGas(e, rules); err != nil { - return err - } - if err := CheckTxs(e.Txs(), rules); err != nil { - return err - } - version := uint8(0) - if rules.Upgrades.Llr { - version = 1 - } - if e.Version() != version { - return ErrWrongVersion - } - return nil -} diff --git a/evm/go-x1/eventcheck/evallcheck/evallcheck.go b/evm/go-x1/eventcheck/evallcheck/evallcheck.go deleted file mode 100644 index 7c89d93..0000000 --- a/evm/go-x1/eventcheck/evallcheck/evallcheck.go +++ /dev/null @@ -1,34 +0,0 @@ -package evallcheck - -import ( - "github.com/Fantom-foundation/go-opera/inter" -) - -type Checker struct { - HeavyCheck HeavyCheck - LightCheck LightCheck -} - -type LightCheck func(evs inter.LlrSignedEpochVote) error - -type HeavyCheck interface { - Enqueue(evs inter.LlrSignedEpochVote, checked func(error)) error -} - -type Callback struct { - HeavyCheck HeavyCheck - LightCheck LightCheck -} - -// Enqueue tries to fill gaps the fetcher's future import queue. -func (c *Checker) Enqueue(evs inter.LlrSignedEpochVote, checked func(error)) { - // Run light checks right away - err := c.LightCheck(evs) - if err != nil { - checked(err) - return - } - - // Run heavy check in parallel - _ = c.HeavyCheck.Enqueue(evs, checked) -} diff --git a/evm/go-x1/eventcheck/gaspowercheck/gas_power_check.go b/evm/go-x1/eventcheck/gaspowercheck/gas_power_check.go deleted file mode 100644 index 954ed5e..0000000 --- a/evm/go-x1/eventcheck/gaspowercheck/gas_power_check.go +++ /dev/null @@ -1,180 +0,0 @@ -package gaspowercheck - -import ( - "errors" - "math/big" - "time" - - "github.com/Fantom-foundation/lachesis-base/eventcheck/epochcheck" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" -) - -var ( - // ErrWrongGasPowerLeft indicates that event's GasPowerLeft is miscalculated. - ErrWrongGasPowerLeft = errors.New("event has wrong GasPowerLeft") -) - -type ValidatorState struct { - PrevEpochEvent iblockproc.EventInfo - GasRefund uint64 -} - -// ValidationContext for gaspower checking -type ValidationContext struct { - Epoch idx.Epoch - Configs [inter.GasPowerConfigs]Config - EpochStart inter.Timestamp - Validators *pos.Validators - ValidatorStates []ValidatorState -} - -// Reader is accessed by the validator to get the current state. -type Reader interface { - GetValidationContext() *ValidationContext -} - -// Config for gaspower checking. There'll be 2 different configs for short-term and long-term gas power checks. -type Config struct { - Idx int - AllocPerSec uint64 - MaxAllocPeriod inter.Timestamp - MinEnsuredAlloc uint64 - StartupAllocPeriod inter.Timestamp - MinStartupGas uint64 -} - -// Checker which checks gas power -type Checker struct { - reader Reader -} - -// New Checker for gas power -func New(reader Reader) *Checker { - return &Checker{ - reader: reader, - } -} - -func mul(a *big.Int, b uint64) { - a.Mul(a, new(big.Int).SetUint64(b)) -} - -func div(a *big.Int, b uint64) { - a.Div(a, new(big.Int).SetUint64(b)) -} - -// CalcGasPower calculates available gas power for the event, i.e. how many gas its content may consume -func (v *Checker) CalcGasPower(e inter.EventI, selfParent inter.EventI) (inter.GasPowerLeft, error) { - ctx := v.reader.GetValidationContext() - // check that all the data is for the same epoch - if ctx.Epoch != e.Epoch() { - return inter.GasPowerLeft{}, epochcheck.ErrNotRelevant - } - - var res inter.GasPowerLeft - for i := range ctx.Configs { - res.Gas[i] = calcGasPower(e, selfParent, ctx, ctx.Configs[i]) - } - - return res, nil -} - -func calcGasPower(e inter.EventI, selfParent inter.EventI, ctx *ValidationContext, config Config) uint64 { - var prevGasPowerLeft uint64 - var prevTime inter.Timestamp - - if e.SelfParent() != nil { - prevGasPowerLeft = selfParent.GasPowerLeft().Gas[config.Idx] - prevTime = selfParent.MedianTime() - } else { - validatorState := ctx.ValidatorStates[ctx.Validators.GetIdx(e.Creator())] - if validatorState.PrevEpochEvent.ID != hash.ZeroEvent { - prevGasPowerLeft = validatorState.PrevEpochEvent.GasPowerLeft.Gas[config.Idx] - prevTime = validatorState.PrevEpochEvent.Time - } else { - prevGasPowerLeft = 0 - prevTime = ctx.EpochStart - } - prevGasPowerLeft += validatorState.GasRefund - } - - return CalcValidatorGasPower(e, e.MedianTime(), prevTime, prevGasPowerLeft, ctx.Validators, config) -} - -func CalcValidatorGasPower(e inter.EventI, eTime, prevTime inter.Timestamp, prevGasPowerLeft uint64, validators *pos.Validators, config Config) uint64 { - gasPowerPerSec, maxGasPower, startup := CalcValidatorGasPowerPerSec(e.Creator(), validators, config) - - if e.SelfParent() == nil { - if prevGasPowerLeft < startup { - prevGasPowerLeft = startup - } - } - - if prevTime > eTime { - prevTime = eTime - } - - gasPowerAllocatedBn := new(big.Int).SetUint64(uint64(eTime - prevTime)) - mul(gasPowerAllocatedBn, gasPowerPerSec) - div(gasPowerAllocatedBn, uint64(time.Second)) - - gasPower := gasPowerAllocatedBn.Uint64() + prevGasPowerLeft - if gasPower > maxGasPower { - gasPower = maxGasPower - } - - return gasPower -} - -func CalcValidatorGasPowerPerSec( - validator idx.ValidatorID, - validators *pos.Validators, - config Config, -) ( - perSec uint64, - maxGasPower uint64, - startup uint64, -) { - stake := validators.Get(validator) - if stake == 0 { - return 0, 0, 0 - } - - gas := config - - validatorGasPowerPerSecBn := new(big.Int).SetUint64(gas.AllocPerSec) - mul(validatorGasPowerPerSecBn, uint64(stake)) - div(validatorGasPowerPerSecBn, uint64(validators.TotalWeight())) - perSec = validatorGasPowerPerSecBn.Uint64() - - maxGasPower = perSec * (uint64(gas.MaxAllocPeriod) / uint64(time.Second)) - if maxGasPower < gas.MinEnsuredAlloc { - maxGasPower = gas.MinEnsuredAlloc - } - - startup = perSec * (uint64(gas.StartupAllocPeriod) / uint64(time.Second)) - if startup < gas.MinStartupGas { - startup = gas.MinStartupGas - } - - return -} - -// Validate event -func (v *Checker) Validate(e inter.EventI, selfParent inter.EventI) error { - gasPowers, err := v.CalcGasPower(e, selfParent) - if err != nil { - return err - } - for i := range gasPowers.Gas { - if e.GasPowerLeft().Gas[i]+e.GasPowerUsed() != gasPowers.Gas[i] { // GasPowerUsed is checked in basic_check - return ErrWrongGasPowerLeft - } - } - return nil -} diff --git a/evm/go-x1/eventcheck/heavycheck/adapters.go b/evm/go-x1/eventcheck/heavycheck/adapters.go deleted file mode 100644 index 694b793..0000000 --- a/evm/go-x1/eventcheck/heavycheck/adapters.go +++ /dev/null @@ -1,31 +0,0 @@ -package heavycheck - -import ( - "github.com/Fantom-foundation/lachesis-base/inter/dag" - - "github.com/Fantom-foundation/go-opera/inter" -) - -type EventsOnly struct { - *Checker -} - -func (c *EventsOnly) Enqueue(e dag.Event, onValidated func(error)) error { - return c.Checker.EnqueueEvent(e.(inter.EventPayloadI), onValidated) -} - -type BVsOnly struct { - *Checker -} - -func (c *BVsOnly) Enqueue(bvs inter.LlrSignedBlockVotes, onValidated func(error)) error { - return c.Checker.EnqueueBVs(bvs, onValidated) -} - -type EVOnly struct { - *Checker -} - -func (c *EVOnly) Enqueue(ers inter.LlrSignedEpochVote, onValidated func(error)) error { - return c.Checker.EnqueueEV(ers, onValidated) -} diff --git a/evm/go-x1/eventcheck/heavycheck/config.go b/evm/go-x1/eventcheck/heavycheck/config.go deleted file mode 100644 index 33d085e..0000000 --- a/evm/go-x1/eventcheck/heavycheck/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package heavycheck - -type Config struct { - MaxQueuedTasks int // the maximum number of tasks to queue up - Threads int -} - -func DefaultConfig() Config { - return Config{ - MaxQueuedTasks: 1024, - Threads: 0, - } -} diff --git a/evm/go-x1/eventcheck/heavycheck/heavy_check.go b/evm/go-x1/eventcheck/heavycheck/heavy_check.go deleted file mode 100644 index 6bb27f5..0000000 --- a/evm/go-x1/eventcheck/heavycheck/heavy_check.go +++ /dev/null @@ -1,313 +0,0 @@ -package heavycheck - -import ( - "bytes" - "errors" - "runtime" - "sync" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - - "github.com/Fantom-foundation/go-opera/eventcheck/basiccheck" - "github.com/Fantom-foundation/go-opera/eventcheck/epochcheck" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/validatorpk" -) - -var ( - ErrWrongEventSig = errors.New("event has wrong signature") - ErrMalformedTxSig = errors.New("tx has wrong signature") - ErrWrongPayloadHash = errors.New("event has wrong payload hash") - ErrPubkeyChanged = errors.New("validator pubkey has changed, cannot create BVs/EV for older epochs") - ErrUnknownEpochEventLocator = errors.New("event locator has unknown epoch") - ErrImpossibleBVsEpoch = errors.New("BVs have an impossible epoch") - ErrUnknownEpochBVs = errors.New("BVs are unprocessable yet") - ErrUnknownEpochEV = errors.New("EV is unprocessable yet") - - errTerminated = errors.New("terminated") // internal err -) - -const ( - // MaxBlocksPerEpoch is chosen so that even if validator chooses the latest non-liable epoch for BVs, - // he still cannot vote for latest blocks (latest = from last 128 epochs), as an epoch has at least one block - // The value is larger than a maximum possible number of blocks - // in an epoch where a single validator doesn't have 2/3W+1 weight - MaxBlocksPerEpoch = idx.Block(basiccheck.MaxLiableEpochs - 128) -) - -// Reader is accessed by the validator to get the current state. -type Reader interface { - GetEpochPubKeys() (map[idx.ValidatorID]validatorpk.PubKey, idx.Epoch) - GetEpochPubKeysOf(idx.Epoch) map[idx.ValidatorID]validatorpk.PubKey - GetEpochBlockStart(idx.Epoch) idx.Block -} - -// Checker which requires only parents list + current epoch info -type Checker struct { - config Config - txSigner types.Signer - reader Reader - - tasksQ chan *taskData - quit chan struct{} - wg sync.WaitGroup -} - -type taskData struct { - event inter.EventPayloadI - bvs *inter.LlrSignedBlockVotes - ev *inter.LlrSignedEpochVote - - onValidated func(error) -} - -// New validator which performs heavy checks, related to signatures validation and Merkle tree validation -func New(config Config, reader Reader, txSigner types.Signer) *Checker { - if config.Threads == 0 { - config.Threads = runtime.NumCPU() - if config.Threads > 1 { - config.Threads-- - } - if config.Threads < 1 { - config.Threads = 1 - } - } - return &Checker{ - config: config, - txSigner: txSigner, - reader: reader, - tasksQ: make(chan *taskData, config.MaxQueuedTasks), - quit: make(chan struct{}), - } -} - -func (v *Checker) Start() { - for i := 0; i < v.config.Threads; i++ { - v.wg.Add(1) - go v.loop() - } -} - -func (v *Checker) Stop() { - close(v.quit) - v.wg.Wait() -} - -func (v *Checker) Overloaded() bool { - return len(v.tasksQ) > v.config.MaxQueuedTasks/2 -} - -func (v *Checker) EnqueueEvent(e inter.EventPayloadI, onValidated func(error)) error { - op := &taskData{ - event: e, - onValidated: onValidated, - } - select { - case v.tasksQ <- op: - return nil - case <-v.quit: - return errTerminated - } -} - -func (v *Checker) EnqueueBVs(bvs inter.LlrSignedBlockVotes, onValidated func(error)) error { - op := &taskData{ - bvs: &bvs, - onValidated: onValidated, - } - select { - case v.tasksQ <- op: - return nil - case <-v.quit: - return errTerminated - } -} - -func (v *Checker) EnqueueEV(ev inter.LlrSignedEpochVote, onValidated func(error)) error { - op := &taskData{ - ev: &ev, - onValidated: onValidated, - } - select { - case v.tasksQ <- op: - return nil - case <-v.quit: - return errTerminated - } -} - -// verifySignature checks the signature against e.Creator. -func verifySignature(signedHash hash.Hash, sig inter.Signature, pubkey validatorpk.PubKey) bool { - if pubkey.Type != validatorpk.Types.Secp256k1 { - return false - } - return crypto.VerifySignature(pubkey.Raw, signedHash.Bytes(), sig.Bytes()) -} - -func (v *Checker) ValidateEventLocator(e inter.SignedEventLocator, authEpoch idx.Epoch, authErr error, checkPayload func() bool) error { - pubkeys := v.reader.GetEpochPubKeysOf(authEpoch) - if len(pubkeys) == 0 { - return authErr - } - pubkey, ok := pubkeys[e.Locator.Creator] - if !ok { - return epochcheck.ErrAuth - } - if checkPayload != nil && !checkPayload() { - return ErrWrongPayloadHash - } - if !verifySignature(e.Locator.HashToSign(), e.Sig, pubkey) { - return ErrWrongEventSig - } - return nil -} - -func (v *Checker) matchPubkey(creator idx.ValidatorID, epoch idx.Epoch, want []byte, authErr error) error { - pubkeys := v.reader.GetEpochPubKeysOf(epoch) - if len(pubkeys) == 0 { - return authErr - } - pubkey, ok := pubkeys[creator] - if !ok { - return epochcheck.ErrAuth - } - if bytes.Compare(pubkey.Bytes(), want) != 0 { - return ErrPubkeyChanged - } - return nil -} - -func (v *Checker) validateBVsEpoch(bvs inter.LlrBlockVotes) error { - actualEpochStart := v.reader.GetEpochBlockStart(bvs.Epoch) - if actualEpochStart == 0 { - return ErrUnknownEpochBVs - } - if bvs.Start < actualEpochStart || bvs.LastBlock() >= actualEpochStart+MaxBlocksPerEpoch { - return ErrImpossibleBVsEpoch - } - return nil -} - -func (v *Checker) ValidateBVs(bvs inter.LlrSignedBlockVotes) error { - if err := v.validateBVsEpoch(bvs.Val); err != nil { - return err - } - return v.ValidateEventLocator(bvs.Signed, bvs.Val.Epoch, ErrUnknownEpochBVs, func() bool { - return bvs.CalcPayloadHash() == bvs.Signed.Locator.PayloadHash - }) -} - -func (v *Checker) ValidateEV(ev inter.LlrSignedEpochVote) error { - return v.ValidateEventLocator(ev.Signed, ev.Val.Epoch-1, ErrUnknownEpochEV, func() bool { - return ev.CalcPayloadHash() == ev.Signed.Locator.PayloadHash - }) -} - -// ValidateEvent runs heavy checks for event -func (v *Checker) ValidateEvent(e inter.EventPayloadI) error { - pubkeys, epoch := v.reader.GetEpochPubKeys() - if e.Epoch() != epoch { - return epochcheck.ErrNotRelevant - } - // validatorID - pubkey, ok := pubkeys[e.Creator()] - if !ok { - return epochcheck.ErrAuth - } - // event sig - if !verifySignature(e.HashToSign(), e.Sig(), pubkey) { - return ErrWrongEventSig - } - // MPs - for _, mp := range e.MisbehaviourProofs() { - if proof := mp.EventsDoublesign; proof != nil { - for _, vote := range proof.Pair { - if err := v.ValidateEventLocator(vote, vote.Locator.Epoch, ErrUnknownEpochEventLocator, nil); err != nil { - return err - } - } - } - if proof := mp.BlockVoteDoublesign; proof != nil { - for _, vote := range proof.Pair { - if err := v.ValidateBVs(vote); err != nil { - return err - } - } - } - if proof := mp.WrongBlockVote; proof != nil { - for _, pal := range proof.Pals { - if err := v.ValidateBVs(pal); err != nil { - return err - } - } - } - if proof := mp.EpochVoteDoublesign; proof != nil { - for _, vote := range proof.Pair { - if err := v.ValidateEV(vote); err != nil { - return err - } - } - } - if proof := mp.WrongEpochVote; proof != nil { - for _, pal := range proof.Pals { - if err := v.ValidateEV(pal); err != nil { - return err - } - } - } - } - // pre-cache tx sig - for _, tx := range e.Txs() { - _, err := types.Sender(v.txSigner, tx) - if err != nil { - return ErrMalformedTxSig - } - } - // Payload hash - if e.PayloadHash() != inter.CalcPayloadHash(e) { - return ErrWrongPayloadHash - } - // Epochs of BVs and EV - if e.EpochVote().Epoch != 0 { - // ensure that validator's pubkey is the same in both current and vote epochs - if err := v.matchPubkey(e.Creator(), e.EpochVote().Epoch-1, pubkey.Bytes(), ErrUnknownEpochEV); err != nil { - return err - } - } - if e.BlockVotes().Epoch != 0 { - // ensure that validator's BVs epoch passes the check - if err := v.validateBVsEpoch(e.BlockVotes()); err != nil { - return err - } - // ensure that validator's pubkey is the same in both current and vote epochs - if e.BlockVotes().Epoch != e.Epoch() { - if err := v.matchPubkey(e.Creator(), e.BlockVotes().Epoch, pubkey.Bytes(), ErrUnknownEpochBVs); err != nil { - return err - } - } - } - - return nil -} - -func (v *Checker) loop() { - defer v.wg.Done() - for { - select { - case op := <-v.tasksQ: - if op.event != nil { - op.onValidated(v.ValidateEvent(op.event)) - } else if op.bvs != nil { - op.onValidated(v.ValidateBVs(*op.bvs)) - } else { - op.onValidated(v.ValidateEV(*op.ev)) - } - - case <-v.quit: - return - } - } -} diff --git a/evm/go-x1/eventcheck/parentlesscheck/parentless_check.go b/evm/go-x1/eventcheck/parentlesscheck/parentless_check.go deleted file mode 100644 index 2da5c28..0000000 --- a/evm/go-x1/eventcheck/parentlesscheck/parentless_check.go +++ /dev/null @@ -1,29 +0,0 @@ -package parentlesscheck - -import ( - "github.com/Fantom-foundation/lachesis-base/inter/dag" -) - -type Checker struct { - HeavyCheck HeavyCheck - LightCheck LightCheck -} - -type LightCheck func(dag.Event) error - -type HeavyCheck interface { - Enqueue(e dag.Event, checked func(error)) error -} - -// Enqueue tries to fill gaps the fetcher's future import queue. -func (c *Checker) Enqueue(e dag.Event, checked func(error)) { - // Run light checks right away - err := c.LightCheck(e) - if err != nil { - checked(err) - return - } - - // Run heavy check in parallel - _ = c.HeavyCheck.Enqueue(e, checked) -} diff --git a/evm/go-x1/eventcheck/parentscheck/parents_check.go b/evm/go-x1/eventcheck/parentscheck/parents_check.go deleted file mode 100644 index e665dca..0000000 --- a/evm/go-x1/eventcheck/parentscheck/parents_check.go +++ /dev/null @@ -1,46 +0,0 @@ -package parentscheck - -import ( - "errors" - - base "github.com/Fantom-foundation/lachesis-base/eventcheck/parentscheck" - - "github.com/Fantom-foundation/go-opera/inter" -) - -var ( - ErrPastTime = errors.New("event has lower claimed time than self-parent") -) - -// Checker which require only parents list + current epoch info -type Checker struct { - base *base.Checker -} - -// New validator which performs checks, which require known the parents -func New() *Checker { - return &Checker{ - base: &base.Checker{}, - } -} - -// Validate event -func (v *Checker) Validate(e inter.EventI, parents inter.EventIs) error { - if err := v.base.Validate(e, parents.Bases()); err != nil { - return err - } - - if e.SelfParent() != nil { - selfParent := parents[0] - if !e.IsSelfParent(selfParent.ID()) { - // sanity check, self-parent is always first, it's how it's stored - return base.ErrWrongSelfParent - } - // selfParent time - if e.CreationTime() <= selfParent.CreationTime() { - return ErrPastTime - } - } - - return nil -} diff --git a/evm/go-x1/evmcore/.gitignore b/evm/go-x1/evmcore/.gitignore deleted file mode 100644 index f725d58..0000000 --- a/evm/go-x1/evmcore/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. -# -# If you find yourself ignoring temporary files generated by your text editor -# or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile ~/.gitignore_global - -/tmp -*/**/*un~ -*un~ -.DS_Store -*/**/.DS_Store - diff --git a/evm/go-x1/evmcore/apply_fake_genesis.go b/evm/go-x1/evmcore/apply_fake_genesis.go deleted file mode 100644 index 8abd7f2..0000000 --- a/evm/go-x1/evmcore/apply_fake_genesis.go +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "crypto/ecdsa" - "errors" - "math" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - - "github.com/Fantom-foundation/go-opera/inter" -) - -var FakeGenesisTime = inter.Timestamp(1608600000 * time.Second) - -// ApplyFakeGenesis writes or updates the genesis block in db. -func ApplyFakeGenesis(statedb *state.StateDB, time inter.Timestamp, balances map[common.Address]*big.Int) (*EvmBlock, error) { - for acc, balance := range balances { - statedb.SetBalance(acc, balance) - } - - // initial block - root, err := flush(statedb, true) - if err != nil { - return nil, err - } - block := genesisBlock(time, root) - - return block, nil -} - -func flush(statedb *state.StateDB, clean bool) (root common.Hash, err error) { - root, err = statedb.Commit(clean) - if err != nil { - return - } - err = statedb.Database().TrieDB().Commit(root, false, nil) - if err != nil { - return - } - - if !clean { - err = statedb.Database().TrieDB().Cap(0) - } - - return -} - -// genesisBlock makes genesis block with pretty hash. -func genesisBlock(time inter.Timestamp, root common.Hash) *EvmBlock { - block := &EvmBlock{ - EvmHeader: EvmHeader{ - Number: big.NewInt(0), - Time: time, - GasLimit: math.MaxUint64, - Root: root, - TxHash: types.EmptyRootHash, - }, - } - - return block -} - -// MustApplyFakeGenesis writes the genesis block and state to db, panicking on error. -func MustApplyFakeGenesis(statedb *state.StateDB, time inter.Timestamp, balances map[common.Address]*big.Int) *EvmBlock { - block, err := ApplyFakeGenesis(statedb, time, balances) - if err != nil { - log.Crit("ApplyFakeGenesis", "err", err) - } - return block -} - -// FakeKey gets n-th fake private key. -func FakeKey(n uint32) *ecdsa.PrivateKey { - var keys = [100]string{ - "0x163f5f0f9a621d72fedd85ffca3d08d131ab4e812181e0d30ffd1c885d20aac7", - "0x3144c0aa4ced56dc15c79b045bc5559a5ac9363d98db6df321fe3847a103740f", - "0x04a531f967898df5dbe223b67989b248e23c1c356a3f6717775cccb7fe53482c", - "0x00ca81d4fe11c23fae8b5e5b06f9fe952c99ca46abaec8bda70a678cd0314dde", - "0x532d9b2ce282fad94efefcf076fdfbe5befe558b145f4cc97f953bcabf087aeb", - "0x6e50dbd3e81b22424cb230133b87bc9ef0f17c584a2a5dc4b212d2b83b5ee084", - "0x2215aaee06a2d64ca32b201e1fb9d1e3c7a25d45a6d8b0de6300ba3a20e42ef5", - "0x1cd6fdfc633c0fa73bd306c46eecd23096365b44ab75f0e6fa04dc2adbea9583", - "0x2fc91d5829f44650c32ba92c8b29d511511446b91badf03b1fd0f808b91a4b5b", - "0x6aeeb7f09e757baa9d3935a042c3d0d46a2eda19e9b676283dce4eaf32e29dc9", - "0x7d51a817ee07c3f28581c47a5072142193337fdca4d7911e58c5af2d03895d1a", - "0x59963733b8a6fb1c6eeb1ce51c7e6046e652a9bcacd4cbaa3f6f26dafe7f79f7", - "0x4cf757812428b0764a871e94b02ba026a5d3738e69f7d1d4f9f93b43ed00e820", - "0xa80a59dc6a9be8003a696ed08a4d37d5046f66201912b40c224d4fe96b515231", - "0xa2ef6534312d205b045a94ec2e9d49191a6d17702671d51dd88a9e2837b612ce", - "0x9512765baac04484c19491feb59fe8ef8ba557e29e00100f3159c8ee35c89038", - "0x700717777c4b7ccdc8c79d6823cb3ea0356ac5e3822accdfa8539cf833caae15", - "0x838ab204f288b4673bbc603ac52c167e8b1c1392cdd96bc02b8fcfadec98cc26", - "0xbf6ba360590e69d1495ea8c0ab2f4a18ebbed7c4bbbe2d823a57719cd40df94f", - "0xd2f091785e9ca0ea2388cf90a046e87552e5cbb4492a9702b83aa32dddf821ac", - "0xad8b51bf6a35a934587413394ab453df559603f885ae3ff0e90c1d90c78153bd", - "0xa1ae301b83bfdd9e4a6ffb277896e5b4438725844fd44b5f733219f9f0a1402b", - "0x9bf39f28aa39153777677711b8ca8a733ffcdad9ec8831713a01d71fb3dbe184", - "0xee948e4413ce4e82ecb51fb6669f82d5af9b0ca4c31924514e6e844e8da46051", - "0xe9a94ddcec56059cffb6dd699011f2bb323293f90613385c8624839296b3d182", - "0xbccc8d4364e82a04ea2dc840ad6eeec6a2c35a51fb01943d58728da7bd4364dc", - "0xd8af1e1f98a3628e91e46888b02cb34b00fd72aee1946409a3435ea806f1ace8", - "0x0ba54f6d7c269ae7d115a17446abe7ba52293997de821d262a3d113fd694d85a", - "0x2666d00809c1ce11da2c7598d3ab54e1bb75263d9e25d8209568a1d5e7cf9cb7", - "0x204b21603d4a076bcdd34db298229f935198ea695964a3e156289728290e6240", - "0xd30f524750dbbef5833dddbcdcdaf6c7f4e43c777d5c468d124170838e83c59d", - "0xee3002a37a510360b0de793b45dd56a4a7a1df843e04cd991441854978b5154e", - "0x410605310cdc3bb8ffe3d472ebf183545e6a09f3b211616156d42d8ad2ee1218", - "0x3d47844c536f73c3558bf2e2238b13b327be2890cad6de60a3940337b8afa774", - "0x114a976408f9a71c581871a6b68f5006df44a178e86d0bc7659d591bb4e56da6", - "0x2c1108cc823ae0c5f496ad61eaab90d0677875ab1b2e0a55a89ecd87388fa9b3", - "0x5fb2462733c28810a8bc68712a08c201ed2b89e822bc7309834476cfa1857acc", - "0x595726750f55bc28a9a2e50f92a6c5fab42e738409cab0008299039c9966e0fe", - "0x6cb89990a3ecf4930470351f1d76a72525d2f702e47d490cc0cc087893d2664a", - "0x275b9ee8df6f2c2d02cd1fb5c343f139867104d5da6f8d82afc771e2d11a28e4", - "0x3a5abe2f6ee961774f0466fca8f986fb0a53c5560b0f239d2a7ce0c8cdb3e1d1", - "0x97bb9f4bb472e89fc5405dd5786ea1de87c5d79758020abb0bfcbf4c48daf9a2", - "0x8ae00c99180aa1f9a8fe2ee7e53aaaedc0e55ff71785f26afa725295d4de78ff", - "0x65e35bf4a097d543df427ec67c192765f6edcbdda54e1b5c0bb5e99507f6a269", - "0x5fa4c34c434e0ddf1f8b3917c3e9ecfcbc09df91237012ff8105bcba275e4b7a", - "0x52ebc273f1da45483d5c6d884f0b65dda891ffee0ea6cdb0c6af90e852984e96", - "0xadec518fdc716a50ffc89c1caf6d2861ffaf02f06656d9275bd5e5d25696c840", - "0xc08f211d4803a2ab2c6c3c0745671decba5564dbebf9d339ae3344d055fd8e1d", - "0x7cf47f78fc8a5a550eae7bc77fb2943dbf8b37dfc381b35ccc6970684ac6cbee", - "0x90659790bafc92adea25095ebfabaffaa5c4bf1d1cc375ab3eac825832181398", - "0xebcae9b7ee8dc6b813fd7aa567f94d9986a7d39a4997ebea3b09db85941cedb5", - "0xde2da353e4200f22614ce98b03e7af8e3f79afa4dcd40666b679525103301606", - "0xd850eca0a7ac46bc01962bcff3cd27fff5e32d401a4a4db3883a3f0e0bdf0933", - "0xabd5c47c0be87b046603c7016258e65c4345aab4a65dde1daf60f2fb3f6c7b0c", - "0xa6c6c5d4c176336017fe715861750fe674b6552755010bd1e8f24cbee19b9b59", - "0xf90b1f7c5e046b894c4c70d93ed74367c4ec260a5ee0051876c929b0a7e98dcb", - "0x15316697d6979fd22c5e3127e030484d94e4e7d78419200e669c3c2d0d9aa2e4", - "0xe86120a57411c86be886b6df0e80ee2061ddf322043ef565b47b548c8072ae31", - "0xe3e66700a59d00d5778c6b732d0e5f90b1516881a76ee4ad232aa7d06ba11e62", - "0xdd876a98e12334ef52ca2d8e149a20b5e085e7e8c6281c2aa60736915073f53f", - "0x30ab7160e3c2ec3884117f91e5189ca1c16af03af36a75cc0169b5f2e8163a88", - "0x2b2a8abbbc4624e33f737bbcf8d864999619e7eb2e92630c2ce3a773c438fba5", - "0xffcad1487800293d08dbe6355f60c170f41ae93906293f2a30c00568f6fb8717", - "0x1b70a964ce916046ba1d3def8fc7d004f213028113e2751e3cf0a12307a21e9f", - "0x4eb12e7c8a1d99a00dc99df7f8c162a929894ab2a638048627a08d9913c02efd", - "0x6944e7e33cafcd099c1b2a88e87e8f57b3fc48a0002c4d168737f55bca9dce6e", - "0x3c2bf03d642d85932ef2f6cc23259f8cc8782c60043c9d7ae58b096a02f9007b", - "0x161c258dc7afadecfe8f8106ab619690ac01f52f669a3b1f453540bf82c78b14", - "0x2941eea6ed3ee2166a0a8ce17f4a7e571cd8fd23ca270cc72839d7bafa955845", - "0x85449300aed219707b7801669597c082dd9e4c74633472610c0009e79422da53", - "0x79254268cf6352f9910405bb8c545aeeee8fbb61293e62663f81355b0ba3d86b", - "0x548c31c260958764c20b417b416223ab8623e8364d84fc8806f665eeb084d6d9", - "0x67edd0d0682a4e7e52575884db12d03b325bd6f8a5e18fb65b143f9f25df04aa", - "0xa262f0ea06bc87c7829dc6fe38d83f99c326976a13c5a0e94da13adc5d136307", - "0x9c655e84994bbe21ac8bade72dd6ebe37491c2986a8e4eb6ab2d007e3f130270", - "0xaf06f1eb84c1f3c9e14e35e6aed34703803fea21dcf628f2bc178325b33148c1", - "0x6aad2dc6d0442b14cfbdcc0ae207c3b88d31e1294606c287d1a6b0cc58670a5f", - "0x7e4e0e156ae1532e98bfda00d850fb476f43b81f09af080446fece7b7d8ac388", - "0xdaf1bfaeb6700798569f6d4815dff9fa6590856c27e6d9aa112cb06d5f21b525", - "0xcd76b0089ef74032756bf06fdd5903c8787957e943e0622f9b35ba84185cb675", - "0xa7b791cf6aae777a7954961b6b5c66b9326ee35ce379f17f554a55bd7cc91d5f", - "0xbb76f0697e3baca59a9b7e5ad449c912ad568d371a1c579bc92b8043479606fc", - "0x95f963b910d735ffd9dfd784ca683cc790aa40acdc5fa9d27fe8e84b6900528d", - "0xe8fa32934f5e6c895f1586114cd3c84caf04f01efab47bcd8bc2efbd743e6dfb", - "0x030076ec9dd721e30c743bea5f0019e80428a97fe900b7245b968c6a6f774313", - "0xb7001594545d584baab7d6b056d3a39c325db2b450787329ed916dd26fa32260", - "0xd2a748ae6cfa9156c94754320b22b35b295dfe779887098386b2cea72f4d0dd2", - "0x258bb5bc5a87c5aebdadb7f83f39029242f0650bc52fc4cc482c89412532db2b", - "0x20ecd5168010ed59a184fd5b5ac528b9fff70ed103ea58c6f35f0137854969b8", - "0x1a517bb0a54425b29b032d4cc28423224963cda64b50ef9731b429660c8da129", - "0xee61ccd710d6dabb81849a1ca2a9369c5484b65517ea80c7772135c55aa9f147", - "0xe906f9f17d6511279053a95feca4a55ef59f97f2596790163ade48067d20238f", - "0x3c8cd94010f44ac08efaae8a31e726bb4fc95564ee7c2e03e7a43ee43f31d6ed", - "0x58ed1a9bde738f0a089ae0c7e18bf77d2489e75f282c1af6e16e0b86fc30c41e", - "0x0be230f443fdc623254292438f0c0f86ba0b799c89d15c9383aa3a64d99628e7", - "0x26a53f1c2b8fff8cfc6ca691777d1c84eb6bef60a3b3c26233c1b12faf653584", - "0x79a6be35f01db3d6a2b659b49f04505a0ce1abf3770494a7a24a83642ae8a675", - "0x54cd7ec556aeeb6f538fe1b7523a86425e520e288be516c95909582e79012bc3", - "0x675e4d1f766213db0791a274e748e858d091460fb4a9222e4b75380f8ecabcdc", - "0x4203c438d4e94bf4a595794b5f5c2882f959face730abb7a7b8acb462c8e138d", - } - - if n == 0 || n > 100 { - panic(errors.New("validator num is out of range")) - } - - key, _ := crypto.ToECDSA(hexutil.MustDecode(keys[n-1])) - return key -} diff --git a/evm/go-x1/evmcore/bench_test.go b/evm/go-x1/evmcore/bench_test.go deleted file mode 100644 index b595285..0000000 --- a/evm/go-x1/evmcore/bench_test.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "crypto/ecdsa" - "io/ioutil" - "math/big" - "os" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/params" -) - -func BenchmarkInsertChain_empty_memdb(b *testing.B) { - benchInsertChain(b, false, nil) -} -func BenchmarkInsertChain_empty_diskdb(b *testing.B) { - benchInsertChain(b, true, nil) -} -func BenchmarkInsertChain_valueTx_memdb(b *testing.B) { - benchInsertChain(b, false, genValueTx(0)) -} -func BenchmarkInsertChain_valueTx_diskdb(b *testing.B) { - benchInsertChain(b, true, genValueTx(0)) -} -func BenchmarkInsertChain_valueTx_100kB_memdb(b *testing.B) { - benchInsertChain(b, false, genValueTx(100*1024)) -} -func BenchmarkInsertChain_valueTx_100kB_diskdb(b *testing.B) { - benchInsertChain(b, true, genValueTx(100*1024)) -} -func BenchmarkInsertChain_ring200_memdb(b *testing.B) { - benchInsertChain(b, false, genTxRing(200)) -} -func BenchmarkInsertChain_ring200_diskdb(b *testing.B) { - benchInsertChain(b, true, genTxRing(200)) -} -func BenchmarkInsertChain_ring1000_memdb(b *testing.B) { - benchInsertChain(b, false, genTxRing(1000)) -} -func BenchmarkInsertChain_ring1000_diskdb(b *testing.B) { - benchInsertChain(b, true, genTxRing(1000)) -} - -var ( - // This is the content of the genesis block used by the benchmarks. - benchRootKey = FakeKey(1) - benchRootAddr = crypto.PubkeyToAddress(benchRootKey.PublicKey) - benchRootFunds = math.BigPow(2, 100) -) - -// genValueTx returns a block generator that includes a single -// value-transfer transaction with n bytes of extra data in each -// block. -func genValueTx(nbytes int) func(int, *BlockGen) { - return func(i int, gen *BlockGen) { - toaddr := common.Address{} - data := make([]byte, nbytes) - gas, _ := IntrinsicGas(data, types.AccessList{}, false) - tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data), types.HomesteadSigner{}, benchRootKey) - gen.AddTx(tx) - } -} - -var ( - ringKeys = make([]*ecdsa.PrivateKey, 1000) - ringAddrs = make([]common.Address, len(ringKeys)) -) - -func init() { - ringKeys[0] = benchRootKey - ringAddrs[0] = benchRootAddr - for i := 1; i < len(ringKeys); i++ { - ringKeys[i], _ = crypto.GenerateKey() - ringAddrs[i] = crypto.PubkeyToAddress(ringKeys[i].PublicKey) - } -} - -// genTxRing returns a block generator that sends ether in a ring -// among n accounts. This is creates n entries in the state database -// and fills the blocks with many small transactions. -func genTxRing(naccounts int) func(int, *BlockGen) { - from := 0 - return func(i int, gen *BlockGen) { - block := gen.PrevBlock(i - 1) - gas := block.GasLimit - for { - gas -= params.TxGas - if gas < params.TxGas { - break - } - to := (from + 1) % naccounts - tx := types.NewTransaction( - gen.TxNonce(ringAddrs[from]), - ringAddrs[to], - benchRootFunds, - params.TxGas, - nil, - nil, - ) - tx, _ = types.SignTx(tx, types.HomesteadSigner{}, ringKeys[from]) - gen.AddTx(tx) - from = to - } - } -} - -func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { - // Create the database in memory or in a temporary directory. - var db ethdb.Database - if !disk { - db = rawdb.NewMemoryDatabase() - } else { - dir, err := ioutil.TempDir("", "eth-core-bench") - if err != nil { - b.Fatalf("cannot create temporary directory: %v", err) - } - defer os.RemoveAll(dir) - db, err = rawdb.NewLevelDBDatabase(dir, 128, 128, "", false) - if err != nil { - b.Fatalf("cannot create temporary database: %v", err) - } - defer db.Close() - } - - // Generate a chain of b.N blocks using the supplied block - // generator function. - // state - statedb, err := state.New(common.Hash{}, state.NewDatabase(db), nil) - if err != nil { - b.Fatalf("cannot create statedb: %v", err) - } - genesisBlock := MustApplyFakeGenesis(statedb, FakeGenesisTime, map[common.Address]*big.Int{ - benchRootAddr: benchRootFunds, - }) - genesisBlock.GasLimit = 1000000 - - // Time the insertion of the new chain. - // State and blocks are stored in the same DB. - b.ReportAllocs() - b.ResetTimer() - - _, _, _ = GenerateChain(nil, genesisBlock, db, b.N, gen) -} diff --git a/evm/go-x1/evmcore/blocks.go b/evm/go-x1/evmcore/blocks.go deleted file mode 100644 index 90bbcf9..0000000 --- a/evm/go-x1/evmcore/blocks.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "github.com/ethereum/go-ethereum/common" -) - -// BadHashes represent a set of manually tracked bad hashes (usually hard forks) -var BadHashes = map[common.Hash]bool{} diff --git a/evm/go-x1/evmcore/chain_makers.go b/evm/go-x1/evmcore/chain_makers.go deleted file mode 100644 index 5d34326..0000000 --- a/evm/go-x1/evmcore/chain_makers.go +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "fmt" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera" -) - -// BlockGen creates blocks for testing. -// See GenerateChain for a detailed explanation. -type BlockGen struct { - i int - parent *EvmBlock - chain []*EvmBlock - header *EvmHeader - statedb *state.StateDB - - gasPool *GasPool - txs []*types.Transaction - receipts []*types.Receipt - - config *params.ChainConfig -} - -type TestChain struct { - headers map[common.Hash]*EvmHeader -} - -func (tc *TestChain) GetHeader(hash common.Hash, number uint64) *EvmHeader { - return tc.headers[hash] -} - -// SetCoinbase sets the coinbase of the generated block. -// It can be called at most once. -func (b *BlockGen) SetCoinbase(addr common.Address) { - if b.gasPool != nil { - if len(b.txs) > 0 { - panic("coinbase must be set before adding transactions") - } - panic("coinbase can only be set once") - } - b.header.Coinbase = addr - b.gasPool = new(GasPool).AddGas(b.header.GasLimit) -} - -// AddTx adds a transaction to the generated block. If no coinbase has -// been set, the block's coinbase is set to the zero address. -// -// AddTx panics if the transaction cannot be executed. In addition to -// the protocol-imposed limitations (gas limit, etc.), there are some -// further limitations on the content of transactions that can be -// added. Notably, contract code relying on the BLOCKHASH instruction -// will panic during execution. -func (b *BlockGen) AddTx(tx *types.Transaction) { - b.AddTxWithChain(nil, tx) -} - -// AddTxWithChain adds a transaction to the generated block. If no coinbase has -// been set, the block's coinbase is set to the zero address. -// -// AddTxWithChain panics if the transaction cannot be executed. In addition to -// the protocol-imposed limitations (gas limit, etc.), there are some -// further limitations on the content of transactions that can be -// added. If contract code relies on the BLOCKHASH instruction, -// the block in chain will be returned. -func (b *BlockGen) AddTxWithChain(bc DummyChain, tx *types.Transaction) { - if b.gasPool == nil { - b.SetCoinbase(common.Address{}) - } - msg, err := TxAsMessage(tx, types.MakeSigner(b.config, b.header.Number), b.header.BaseFee) - if err != nil { - panic(err) - } - b.statedb.Prepare(tx.Hash(), len(b.txs)) - blockContext := NewEVMBlockContext(b.header, bc, nil) - vmenv := vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.config, opera.DefaultVMConfig) - receipt, _, _, err := applyTransaction(msg, b.config, b.gasPool, b.statedb, b.header.Number, b.header.Hash, tx, &b.header.GasUsed, vmenv, func(log *types.Log, db *state.StateDB) {}) - if err != nil { - panic(err) - } - b.txs = append(b.txs, tx) - b.receipts = append(b.receipts, receipt) -} - -// GetBalance returns the balance of the given address at the generated block. -func (b *BlockGen) GetBalance(addr common.Address) *big.Int { - return b.statedb.GetBalance(addr) -} - -// AddUncheckedTx forcefully adds a transaction to the block without any -// validation. -// -// AddUncheckedTx will cause consensus failures when used during real -// chain processing. This is best used in conjunction with raw block insertion. -func (b *BlockGen) AddUncheckedTx(tx *types.Transaction) { - b.txs = append(b.txs, tx) -} - -// Number returns the block number of the block being generated. -func (b *BlockGen) Number() *big.Int { - return new(big.Int).Set(b.header.Number) -} - -// BaseFee returns the EIP-1559 base fee of the block being generated. -func (b *BlockGen) BaseFee() *big.Int { - return new(big.Int).Set(b.header.BaseFee) -} - -// AddUncheckedReceipt forcefully adds a receipts to the block without a -// backing transaction. -// -// AddUncheckedReceipt will cause consensus failures when used during real -// chain processing. This is best used in conjunction with raw block insertion. -func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt) { - b.receipts = append(b.receipts, receipt) -} - -// TxNonce returns the next valid transaction nonce for the -// account at addr. It panics if the account does not exist. -func (b *BlockGen) TxNonce(addr common.Address) uint64 { - if !b.statedb.Exist(addr) { - panic("account does not exist") - } - return b.statedb.GetNonce(addr) -} - -// PrevBlock returns a previously generated block by number. It panics if -// num is greater or equal to the number of the block being generated. -// For index -1, PrevBlock returns the parent block given to GenerateChain. -func (b *BlockGen) PrevBlock(index int) *EvmBlock { - if index >= b.i { - panic(fmt.Errorf("block index %d out of range (%d,%d)", index, -1, b.i)) - } - if index == -1 { - return b.parent - } - return b.chain[index] -} - -// OffsetTime modifies the time instance of a block, implicitly changing its -// associated difficulty. It's useful to test scenarios where forking is not -// tied to chain length directly. -func (b *BlockGen) OffsetTime(seconds int64) { - b.header.Time += inter.Timestamp(seconds) - if b.header.Time <= b.parent.Header().Time { - panic("block time out of range") - } -} - -// GenerateChain creates a chain of n blocks. The first block's -// parent will be the provided parent. db is used to store -// intermediate states and should contain the parent's state trie. -// -// The generator function is called with a new block generator for -// every block. Any transactions and uncles added to the generator -// become part of the block. If gen is nil, the blocks will be empty -// and their coinbase will be the zero address. -// -// Blocks created by GenerateChain do not contain valid proof of work -// values. Inserting them into BlockChain requires use of FakePow or -// a similar non-validating proof of work implementation. -func GenerateChain(config *params.ChainConfig, parent *EvmBlock, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*EvmBlock, []types.Receipts, DummyChain) { - if config == nil { - config = params.AllEthashProtocolChanges - } - - chain := &TestChain{ - headers: map[common.Hash]*EvmHeader{}, - } - - blocks, receipts := make([]*EvmBlock, n), make([]types.Receipts, n) - genblock := func(i int, parent *EvmBlock, statedb *state.StateDB) (*EvmBlock, types.Receipts) { - b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config} - b.header = makeHeader(parent, statedb) - - // Execute any user modifications to the block - if gen != nil { - gen(i, b) - } - // Finalize and seal the block - block := &EvmBlock{ - EvmHeader: *b.header, - } - - // Write state changes to db - root, err := flush(statedb, config.IsEIP158(b.header.Number)) - if err != nil { - panic(fmt.Sprintf("state flush error: %v", err)) - } - - b.header = block.Header() - block.Root = root - - return block, b.receipts - } - for i := 0; i < n; i++ { - statedb, err := state.New(parent.Root, state.NewDatabase(db), nil) - if err != nil { - panic(err) - } - block, receipt := genblock(i, parent, statedb) - blocks[i] = block - receipts[i] = receipt - parent = block - - chain.headers[block.Hash] = block.Header() - } - return blocks, receipts, chain -} - -func makeHeader(parent *EvmBlock, state *state.StateDB) *EvmHeader { - var t inter.Timestamp - if parent.Time == 0 { - t = 10 - } else { - t = parent.Time + inter.Timestamp(10*time.Second) // block time is fixed at 10 seconds - } - header := &EvmHeader{ - ParentHash: parent.Hash, - Coinbase: parent.Coinbase, - GasLimit: parent.GasLimit, - BaseFee: parent.BaseFee, - Number: new(big.Int).Add(parent.Number, common.Big1), - Time: t, - } - return header -} - -// makeHeaderChain creates a deterministic chain of headers rooted at parent. -func makeHeaderChain(parent *EvmHeader, n int, db ethdb.Database, seed int) []*EvmHeader { - block := &EvmBlock{} - block.EvmHeader = *parent - - blocks := makeBlockChain(block, n, db, seed) - headers := make([]*EvmHeader, len(blocks)) - for i, block := range blocks { - headers[i] = block.Header() - } - return headers -} - -// makeBlockChain creates a deterministic chain of blocks rooted at parent. -func makeBlockChain(parent *EvmBlock, n int, db ethdb.Database, seed int) []*EvmBlock { - blocks, _, _ := GenerateChain(params.TestChainConfig, parent, db, n, func(i int, b *BlockGen) { - b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) - }) - return blocks -} - -type fakeChainReader struct { - config *params.ChainConfig - genesis *EvmBlock -} - -// Config returns the chain configuration. -func (cr *fakeChainReader) Config() *params.ChainConfig { - return cr.config -} - -func (cr *fakeChainReader) CurrentHeader() *EvmHeader { return nil } -func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *EvmHeader { return nil } -func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *EvmHeader { return nil } -func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *EvmHeader { return nil } -func (cr *fakeChainReader) GetBlock(hash common.Hash, number uint64) *EvmBlock { return nil } diff --git a/evm/go-x1/evmcore/dummy_block.go b/evm/go-x1/evmcore/dummy_block.go deleted file mode 100644 index cede4cc..0000000 --- a/evm/go-x1/evmcore/dummy_block.go +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "math" - "math/big" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/trie" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera" -) - -type ( - EvmHeader struct { - Number *big.Int - Hash common.Hash - ParentHash common.Hash - Root common.Hash - TxHash common.Hash - Time inter.Timestamp - Coinbase common.Address - - GasLimit uint64 - GasUsed uint64 - - BaseFee *big.Int - } - - EvmBlock struct { - EvmHeader - - Transactions types.Transactions - } -) - -// NewEvmBlock constructor. -func NewEvmBlock(h *EvmHeader, txs types.Transactions) *EvmBlock { - b := &EvmBlock{ - EvmHeader: *h, - Transactions: txs, - } - - if len(txs) == 0 { - b.EvmHeader.TxHash = types.EmptyRootHash - } else { - b.EvmHeader.TxHash = types.DeriveSha(txs, trie.NewStackTrie(nil)) - } - - return b -} - -// ToEvmHeader converts inter.Block to EvmHeader. -func ToEvmHeader(block *inter.Block, index idx.Block, prevHash hash.Event, rules opera.Rules) *EvmHeader { - baseFee := rules.Economy.MinGasPrice - if !rules.Upgrades.London { - baseFee = nil - } - return &EvmHeader{ - Hash: common.Hash(block.Atropos), - ParentHash: common.Hash(prevHash), - Root: common.Hash(block.Root), - Number: big.NewInt(int64(index)), - Time: block.Time, - GasLimit: math.MaxUint64, - GasUsed: block.GasUsed, - BaseFee: baseFee, - } -} - -// ConvertFromEthHeader converts ETH-formatted header to Lachesis EVM header -func ConvertFromEthHeader(h *types.Header) *EvmHeader { - // NOTE: incomplete conversion - return &EvmHeader{ - Number: h.Number, - Coinbase: h.Coinbase, - GasLimit: math.MaxUint64, - GasUsed: h.GasUsed, - Root: h.Root, - TxHash: h.TxHash, - ParentHash: h.ParentHash, - Time: inter.FromUnix(int64(h.Time)), - Hash: common.BytesToHash(h.Extra), - BaseFee: h.BaseFee, - } -} - -// EthHeader returns header in ETH format -func (h *EvmHeader) EthHeader() *types.Header { - if h == nil { - return nil - } - // NOTE: incomplete conversion - ethHeader := &types.Header{ - Number: h.Number, - Coinbase: h.Coinbase, - GasLimit: 0xffffffffffff, // don't use h.GasLimit (too much bits) here to avoid parsing issues - GasUsed: h.GasUsed, - Root: h.Root, - TxHash: h.TxHash, - ParentHash: h.ParentHash, - Time: uint64(h.Time.Unix()), - Extra: h.Hash.Bytes(), - BaseFee: h.BaseFee, - - Difficulty: new(big.Int), - } - ethHeader.SetExternalHash(h.Hash) - return ethHeader -} - -// Header is a copy of EvmBlock.EvmHeader. -func (b *EvmBlock) Header() *EvmHeader { - if b == nil { - return nil - } - // copy values - h := b.EvmHeader - // copy refs - h.Number = new(big.Int).Set(b.Number) - if b.BaseFee != nil { - h.BaseFee = new(big.Int).Set(b.BaseFee) - } - - return &h -} - -func (b *EvmBlock) NumberU64() uint64 { - return b.Number.Uint64() -} - -func (b *EvmBlock) EthBlock() *types.Block { - if b == nil { - return nil - } - return types.NewBlock(b.EvmHeader.EthHeader(), b.Transactions, nil, nil, trie.NewStackTrie(nil)) -} - -func (b *EvmBlock) EstimateSize() int { - est := 0 - for _, tx := range b.Transactions { - est += len(tx.Data()) - } - return est + b.Transactions.Len()*256 -} diff --git a/evm/go-x1/evmcore/error.go b/evm/go-x1/evmcore/error.go deleted file mode 100644 index cba6781..0000000 --- a/evm/go-x1/evmcore/error.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "errors" - - "github.com/ethereum/go-ethereum/core/types" -) - -var ( - // ErrNoGenesis is returned when there is no Genesis Block. - ErrNoGenesis = errors.New("genesis not found in chain") -) - -// List of evm-call-message pre-checking errors. All state transition messages will -// be pre-checked before execution. If any invalidation detected, the corresponding -// error should be returned which is defined here. -// -// - If the pre-checking happens in the miner, then the transaction won't be packed. -// - If the pre-checking happens in the block processing procedure, then a "BAD BLOCk" -// error should be emitted. -var ( - // ErrNonceTooLow is returned if the nonce of a transaction is lower than the - // one present in the local chain. - ErrNonceTooLow = errors.New("nonce too low") - - // ErrNonceTooHigh is returned if the nonce of a transaction is higher than the - // next one expected based on the local chain. - ErrNonceTooHigh = errors.New("nonce too high") - - // ErrGasLimitReached is returned by the gas pool if the amount of gas required - // by a transaction is higher than what's left in the block. - ErrGasLimitReached = errors.New("gas limit reached") - - // ErrInsufficientFundsForTransfer is returned if the transaction sender doesn't - // have enough funds for transfer(topmost call only). - ErrInsufficientFundsForTransfer = errors.New("insufficient funds for transfer") - - // ErrInsufficientFunds is returned if the total cost of executing a transaction - // is higher than the balance of the user's account. - ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") - - // ErrGasUintOverflow is returned when calculating gas usage. - ErrGasUintOverflow = errors.New("gas uint64 overflow") - - // ErrIntrinsicGas is returned if the transaction is specified to use less gas - // than required to start the invocation. - ErrIntrinsicGas = errors.New("intrinsic gas too low") - - // ErrTxTypeNotSupported is returned if a transaction is not supported in the - // current network configuration. - ErrTxTypeNotSupported = types.ErrTxTypeNotSupported - - // ErrTipAboveFeeCap is a sanity error to ensure no one is able to specify a - // transaction with a tip higher than the total fee cap. - ErrTipAboveFeeCap = errors.New("max priority fee per gas higher than max fee per gas") - - // ErrTipVeryHigh is a sanity error to avoid extremely big numbers specified - // in the tip field. - ErrTipVeryHigh = errors.New("max priority fee per gas higher than 2^256-1") - - // ErrFeeCapVeryHigh is a sanity error to avoid extremely big numbers specified - // in the fee cap field. - ErrFeeCapVeryHigh = errors.New("max fee per gas higher than 2^256-1") - - // ErrFeeCapTooLow is returned if the transaction fee cap is less than the - // the base fee of the block. - ErrFeeCapTooLow = errors.New("max fee per gas less than block base fee") - - // ErrSenderNoEOA is returned if the sender of a transaction is a contract. - ErrSenderNoEOA = errors.New("sender not an eoa") -) diff --git a/evm/go-x1/evmcore/evm.go b/evm/go-x1/evmcore/evm.go deleted file mode 100644 index 8958754..0000000 --- a/evm/go-x1/evmcore/evm.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" -) - -// DummyChain supports retrieving headers and consensus parameters from the -// current blockchain to be used during transaction processing. -type DummyChain interface { - // GetHeader returns the hash corresponding to their hash. - GetHeader(common.Hash, uint64) *EvmHeader -} - -// NewEVMBlockContext creates a new context for use in the EVM. -func NewEVMBlockContext(header *EvmHeader, chain DummyChain, author *common.Address) vm.BlockContext { - var ( - beneficiary common.Address - baseFee *big.Int - ) - // If we don't have an explicit author (i.e. not mining), extract from the header - if author == nil { - beneficiary = header.Coinbase - } else { - beneficiary = *author - } - if header.BaseFee != nil { - baseFee = new(big.Int).Set(header.BaseFee) - } - return vm.BlockContext{ - CanTransfer: CanTransfer, - Transfer: Transfer, - GetHash: GetHashFn(header, chain), - Coinbase: beneficiary, - BlockNumber: new(big.Int).Set(header.Number), - Time: new(big.Int).SetUint64(uint64(header.Time.Unix())), - Difficulty: big.NewInt(1), - BaseFee: baseFee, - GasLimit: header.GasLimit, - } -} - -// NewEVMTxContext creates a new transaction context for a single transaction. -func NewEVMTxContext(msg Message) vm.TxContext { - return vm.TxContext{ - Origin: msg.From(), - GasPrice: new(big.Int).Set(msg.GasPrice()), - } -} - -// GetHashFn returns a GetHashFunc which retrieves header hashes by number -func GetHashFn(ref *EvmHeader, chain DummyChain) func(n uint64) common.Hash { - // Cache will initially contain [refHash.parent], - // Then fill up with [refHash.p, refHash.pp, refHash.ppp, ...] - var cache []common.Hash - - return func(n uint64) common.Hash { - // If there's no hash cache yet, make one - if len(cache) == 0 { - cache = append(cache, ref.ParentHash) - } - if idx := ref.Number.Uint64() - n - 1; idx < uint64(len(cache)) { - return cache[idx] - } - // No luck in the cache, but we can start iterating from the last element we already know - lastKnownHash := cache[len(cache)-1] - lastKnownNumber := ref.Number.Uint64() - uint64(len(cache)) - - for { - header := chain.GetHeader(lastKnownHash, lastKnownNumber) - if header == nil { - break - } - cache = append(cache, header.ParentHash) - lastKnownHash = header.ParentHash - lastKnownNumber = header.Number.Uint64() - 1 - if n == lastKnownNumber { - return lastKnownHash - } - } - return common.Hash{} - } -} - -// CanTransfer checks whether there are enough funds in the address' account to make a transfer. -// This does not take the necessary gas in to account to make the transfer valid. -func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool { - return db.GetBalance(addr).Cmp(amount) >= 0 -} - -// Transfer subtracts amount from sender and adds amount to recipient using the given Db -func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) { - db.SubBalance(sender, amount) - db.AddBalance(recipient, amount) -} diff --git a/evm/go-x1/evmcore/gaspool.go b/evm/go-x1/evmcore/gaspool.go deleted file mode 100644 index ec43763..0000000 --- a/evm/go-x1/evmcore/gaspool.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "fmt" - "math" -) - -// GasPool tracks the amount of gas available during execution of the transactions -// in a block. The zero value is a pool with zero gas available. -type GasPool uint64 - -// AddGas makes gas available for execution. -func (gp *GasPool) AddGas(amount uint64) *GasPool { - if uint64(*gp) > math.MaxUint64-amount { - panic("gas pool pushed above uint64") - } - *(*uint64)(gp) += amount - return gp -} - -// SubGas deducts the given amount from the pool if enough gas is -// available and returns an error otherwise. -func (gp *GasPool) SubGas(amount uint64) error { - if uint64(*gp) < amount { - return ErrGasLimitReached - } - *(*uint64)(gp) -= amount - return nil -} - -// Gas returns the amount of gas remaining in the pool. -func (gp *GasPool) Gas() uint64 { - return uint64(*gp) -} - -func (gp *GasPool) String() string { - return fmt.Sprintf("%d", *gp) -} diff --git a/evm/go-x1/evmcore/helper_test.go b/evm/go-x1/evmcore/helper_test.go deleted file mode 100644 index 10905e2..0000000 --- a/evm/go-x1/evmcore/helper_test.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "container/list" - - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/ethdb" - notify "github.com/ethereum/go-ethereum/event" -) - -// Implement our EthTest Manager -type TestManager struct { - // stateManager *StateManager - eventMux *notify.TypeMux - - db ethdb.Database - txPool *TxPool - bc DummyChain - Blocks []*EvmBlock -} - -func (tm *TestManager) IsListening() bool { - return false -} - -func (tm *TestManager) IsMining() bool { - return false -} - -func (tm *TestManager) PeerCount() int { - return 0 -} - -func (tm *TestManager) Peers() *list.List { - return list.New() -} - -func (tm *TestManager) BlockChain() DummyChain { - return tm.bc -} - -func (tm *TestManager) TxPool() *TxPool { - return tm.txPool -} - -// func (tm *TestManager) StateManager() *StateManager { -// return tm.stateManager -// } - -func (tm *TestManager) EventMux() *notify.TypeMux { - return tm.eventMux -} - -// func (tm *TestManager) KeyManager() *crypto.KeyManager { -// return nil -// } - -func (tm *TestManager) Db() ethdb.Database { - return tm.db -} - -func NewTestManager() *TestManager { - testManager := &TestManager{} - testManager.eventMux = new(notify.TypeMux) - testManager.db = rawdb.NewMemoryDatabase() - // testManager.txPool = NewTxPool(testManager) - // testManager.blockChain = NewBlockChain(testManager) - // testManager.stateManager = NewStateManager(testManager) - return testManager -} diff --git a/evm/go-x1/evmcore/notify.go b/evm/go-x1/evmcore/notify.go deleted file mode 100644 index ac5f4dd..0000000 --- a/evm/go-x1/evmcore/notify.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -// NewTxsNotify is posted when a batch of transactions enter the transaction pool. -type NewTxsNotify struct{ Txs []*types.Transaction } - -// PendingLogsNotify is posted pre mining and notifies of pending logs. -type PendingLogsNotify struct { - Logs []*types.Log -} - -// NewMinedBlockNotify is posted when a block has been imported. -type NewMinedBlockNotify struct{ Block *EvmBlock } - -// RemovedLogsNotify is posted when a reorg happens -type RemovedLogsNotify struct{ Logs []*types.Log } - -type ChainNotify struct { - Block *EvmBlock - Hash common.Hash - Logs []*types.Log -} - -type ChainSideNotify struct { - Block *EvmBlock -} - -type ChainHeadNotify struct{ Block *EvmBlock } diff --git a/evm/go-x1/evmcore/state_prefetcher.go b/evm/go-x1/evmcore/state_prefetcher.go deleted file mode 100644 index dac3d1e..0000000 --- a/evm/go-x1/evmcore/state_prefetcher.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "sync/atomic" - - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/utils/signers/gsignercache" -) - -// statePrefetcher is a basic Prefetcher, which blindly executes a block on top -// of an arbitrary state with the goal of prefetching potentially useful state -// data from disk before the main block processor start executing. -type statePrefetcher struct { - config *params.ChainConfig // Chain configuration options - bc DummyChain // Canonical block chain -} - -// newStatePrefetcher initialises a new statePrefetcher. -func newStatePrefetcher(config *params.ChainConfig, bc DummyChain) *statePrefetcher { - return &statePrefetcher{ - config: config, - bc: bc, - } -} - -// Prefetch processes the state changes according to the Ethereum rules by running -// the transaction messages using the statedb, but any changes are discarded. The -// only goal is to pre-cache transaction signatures and state trie nodes. -func (p *statePrefetcher) Prefetch(block *EvmBlock, statedb *state.StateDB, cfg vm.Config, interrupt *uint32) { - var ( - header = block.Header() - gaspool = new(GasPool).AddGas(block.GasLimit) - blockContext = NewEVMBlockContext(header, p.bc, nil) - evm = vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) - signer = gsignercache.Wrap(types.MakeSigner(p.config, header.Number)) - ) - // Iterate over and process the individual transactions - byzantium := p.config.IsByzantium(block.Number) - for i, tx := range block.Transactions { - // If block precaching was interrupted, abort - if interrupt != nil && atomic.LoadUint32(interrupt) == 1 { - return - } - // Convert the transaction into an executable message and pre-cache its sender - msg, err := TxAsMessage(tx, signer, header.BaseFee) - if err != nil { - return // Also invalid block, bail out - } - statedb.Prepare(tx.Hash(), i) - if err := precacheTransaction(msg, p.config, gaspool, statedb, header, evm); err != nil { - return // Ugh, something went horribly wrong, bail out - } - // If we're pre-byzantium, pre-load trie nodes for the intermediate root - if !byzantium { - statedb.IntermediateRoot(true) - } - } - // If were post-byzantium, pre-load trie nodes for the final root hash - if byzantium { - statedb.IntermediateRoot(true) - } -} - -// precacheTransaction attempts to apply a transaction to the given state database -// and uses the input parameters for its environment. The goal is not to execute -// the transaction successfully, rather to warm up touched data slots. -func precacheTransaction(msg types.Message, config *params.ChainConfig, gaspool *GasPool, statedb *state.StateDB, header *EvmHeader, evm *vm.EVM) error { - // Update the evm with the new transaction context. - evm.Reset(NewEVMTxContext(msg), statedb) - // Add addresses to access list if applicable - _, err := ApplyMessage(evm, msg, gaspool) - return err -} diff --git a/evm/go-x1/evmcore/state_processor.go b/evm/go-x1/evmcore/state_processor.go deleted file mode 100644 index 9316995..0000000 --- a/evm/go-x1/evmcore/state_processor.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/utils/signers/gsignercache" - "github.com/Fantom-foundation/go-opera/utils/signers/internaltx" -) - -// StateProcessor is a basic Processor, which takes care of transitioning -// state from one point to another. -// -// StateProcessor implements Processor. -type StateProcessor struct { - config *params.ChainConfig // Chain configuration options - bc DummyChain // Canonical block chain -} - -// NewStateProcessor initialises a new StateProcessor. -func NewStateProcessor(config *params.ChainConfig, bc DummyChain) *StateProcessor { - return &StateProcessor{ - config: config, - bc: bc, - } -} - -// Process processes the state changes according to the Ethereum rules by running -// the transaction messages using the statedb and applying any rewards to both -// the processor (coinbase) and any included uncles. -// -// Process returns the receipts and logs accumulated during the process and -// returns the amount of gas that was used in the process. If any of the -// transactions failed to execute due to insufficient gas it will return an error. -func (p *StateProcessor) Process( - block *EvmBlock, statedb *state.StateDB, cfg vm.Config, usedGas *uint64, onNewLog func(*types.Log, *state.StateDB), -) ( - receipts types.Receipts, allLogs []*types.Log, skipped []uint32, err error, -) { - skipped = make([]uint32, 0, len(block.Transactions)) - var ( - gp = new(GasPool).AddGas(block.GasLimit) - receipt *types.Receipt - skip bool - header = block.Header() - blockContext = NewEVMBlockContext(header, p.bc, nil) - vmenv = vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) - blockHash = block.Hash - blockNumber = block.Number - signer = gsignercache.Wrap(types.MakeSigner(p.config, header.Number)) - ) - // Iterate over and process the individual transactions - for i, tx := range block.Transactions { - msg, err := TxAsMessage(tx, signer, header.BaseFee) - if err != nil { - return nil, nil, nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) - } - - statedb.Prepare(tx.Hash(), i) - receipt, _, skip, err = applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, onNewLog) - if skip { - skipped = append(skipped, uint32(i)) - err = nil - continue - } - if err != nil { - return nil, nil, nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) - } - receipts = append(receipts, receipt) - allLogs = append(allLogs, receipt.Logs...) - } - return -} - -func applyTransaction( - msg types.Message, - config *params.ChainConfig, - gp *GasPool, - statedb *state.StateDB, - blockNumber *big.Int, - blockHash common.Hash, - tx *types.Transaction, - usedGas *uint64, - evm *vm.EVM, - onNewLog func(*types.Log, *state.StateDB), -) ( - *types.Receipt, - uint64, - bool, - error, -) { - // Create a new context to be used in the EVM environment. - txContext := NewEVMTxContext(msg) - evm.Reset(txContext, statedb) - - // Apply the transaction to the current state (included in the env). - result, err := ApplyMessage(evm, msg, gp) - if err != nil { - return nil, 0, result == nil, err - } - // Notify about logs with potential state changes - logs := statedb.GetLogs(tx.Hash(), blockHash) - for _, l := range logs { - onNewLog(l, statedb) - } - - // Update the state with pending changes. - var root []byte - if config.IsByzantium(blockNumber) { - statedb.Finalise(true) - } else { - root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes() - } - *usedGas += result.UsedGas - - // Create a new receipt for the transaction, storing the intermediate root and gas used - // by the tx. - receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: *usedGas} - if result.Failed() { - receipt.Status = types.ReceiptStatusFailed - } else { - receipt.Status = types.ReceiptStatusSuccessful - } - receipt.TxHash = tx.Hash() - receipt.GasUsed = result.UsedGas - - // If the transaction created a contract, store the creation address in the receipt. - if msg.To() == nil { - receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce()) - } - - // Set the receipt logs. - receipt.Logs = logs - receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) - receipt.BlockHash = blockHash - receipt.BlockNumber = blockNumber - receipt.TransactionIndex = uint(statedb.TxIndex()) - return receipt, result.UsedGas, false, err -} - -func TxAsMessage(tx *types.Transaction, signer types.Signer, baseFee *big.Int) (types.Message, error) { - if !internaltx.IsInternal(tx) { - return tx.AsMessage(signer, baseFee) - } else { - msg := types.NewMessage(internaltx.InternalSender(tx), tx.To(), tx.Nonce(), tx.Value(), tx.Gas(), tx.GasPrice(), tx.GasFeeCap(), tx.GasTipCap(), tx.Data(), tx.AccessList(), true) - return msg, nil - } -} diff --git a/evm/go-x1/evmcore/state_transition.go b/evm/go-x1/evmcore/state_transition.go deleted file mode 100644 index 1fee3d1..0000000 --- a/evm/go-x1/evmcore/state_transition.go +++ /dev/null @@ -1,334 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "fmt" - "math" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" -) - -var emptyCodeHash = crypto.Keccak256Hash(nil) - -/* -The State Transitioning Model - -A state transition is a change made when a transaction is applied to the current world state -The state transitioning model does all the necessary work to work out a valid new state root. - -1) Nonce handling -2) Pre pay gas -3) Create a new state object if the recipient is \0*32 -4) Value transfer -== If contract creation == - 4a) Attempt to run transaction data - 4b) If valid, use result as code for the new state object -== end == -5) Run Script section -6) Derive new state root -*/ -type StateTransition struct { - gp *GasPool - msg Message - gas uint64 - gasPrice *big.Int - initialGas uint64 - value *big.Int - data []byte - state vm.StateDB - evm *vm.EVM -} - -// Message represents a message sent to a contract. -type Message interface { - From() common.Address - To() *common.Address - - GasPrice() *big.Int - GasFeeCap() *big.Int - GasTipCap() *big.Int - Gas() uint64 - Value() *big.Int - - Nonce() uint64 - IsFake() bool - Data() []byte - AccessList() types.AccessList -} - -// ExecutionResult includes all output after executing given evm -// message no matter the execution itself is successful or not. -type ExecutionResult struct { - UsedGas uint64 // Total used gas but include the refunded gas - Err error // Any error encountered during the execution(listed in core/vm/errors.go) - ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode) -} - -// Unwrap returns the internal evm error which allows us for further -// analysis outside. -func (result *ExecutionResult) Unwrap() error { - return result.Err -} - -// Failed returns the indicator whether the execution is successful or not -func (result *ExecutionResult) Failed() bool { return result.Err != nil } - -// Return is a helper function to help caller distinguish between revert reason -// and function return. Return returns the data after execution if no error occurs. -func (result *ExecutionResult) Return() []byte { - if result.Err != nil { - return nil - } - return common.CopyBytes(result.ReturnData) -} - -// Revert returns the concrete revert reason if the execution is aborted by `REVERT` -// opcode. Note the reason can be nil if no data supplied with revert opcode. -func (result *ExecutionResult) Revert() []byte { - if result.Err != vm.ErrExecutionReverted { - return nil - } - return common.CopyBytes(result.ReturnData) -} - -// IntrinsicGas computes the 'intrinsic gas' for a message with the given data. -func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool) (uint64, error) { - // Set the starting gas for the raw transaction - var gas uint64 - if isContractCreation { - gas = params.TxGasContractCreation - } else { - gas = params.TxGas - } - // Bump the required gas by the amount of transactional data - if len(data) > 0 { - // Zero and non-zero bytes are priced differently - var nz uint64 - for _, byt := range data { - if byt != 0 { - nz++ - } - } - // Make sure we don't exceed uint64 for all data combinations - if (math.MaxUint64-gas)/params.TxDataNonZeroGasEIP2028 < nz { - return 0, vm.ErrOutOfGas - } - gas += nz * params.TxDataNonZeroGasEIP2028 - - z := uint64(len(data)) - nz - if (math.MaxUint64-gas)/params.TxDataZeroGas < z { - return 0, ErrGasUintOverflow - } - gas += z * params.TxDataZeroGas - } - if accessList != nil { - gas += uint64(len(accessList)) * params.TxAccessListAddressGas - gas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas - } - return gas, nil -} - -// NewStateTransition initialises and returns a new state transition object. -func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition { - return &StateTransition{ - gp: gp, - evm: evm, - msg: msg, - gasPrice: msg.GasPrice(), - value: msg.Value(), - data: msg.Data(), - state: evm.StateDB, - } -} - -// ApplyMessage computes the new state by applying the given message -// against the old state within the environment. -// -// ApplyMessage returns the bytes returned by any EVM execution (if it took place), -// the gas used (which includes gas refunds) and an error if it failed. An error always -// indicates a core error meaning that the message would always fail for that particular -// state and would never be accepted within a block. -func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) (*ExecutionResult, error) { - res, err := NewStateTransition(evm, msg, gp).TransitionDb() - if err != nil { - log.Debug("Tx skipped", "err", err) - } - return res, err -} - -// to returns the recipient of the message. -func (st *StateTransition) to() common.Address { - if st.msg == nil || st.msg.To() == nil /* contract creation */ { - return common.Address{} - } - return *st.msg.To() -} - -func (st *StateTransition) buyGas() error { - mgval := new(big.Int).SetUint64(st.msg.Gas()) - mgval = mgval.Mul(mgval, st.gasPrice) - // Note: Opera doesn't need to check against gasFeeCap instead of gasPrice, as it's too aggressive in the asynchronous environment - if have, want := st.state.GetBalance(st.msg.From()), mgval; have.Cmp(want) < 0 { - return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want) - } - if err := st.gp.SubGas(st.msg.Gas()); err != nil { - return err - } - st.gas += st.msg.Gas() - - st.initialGas = st.msg.Gas() - st.state.SubBalance(st.msg.From(), mgval) - return nil -} - -func (st *StateTransition) preCheck() error { - // Only check transactions that are not fake - if !st.msg.IsFake() { - // Make sure this transaction's nonce is correct. - stNonce := st.state.GetNonce(st.msg.From()) - if msgNonce := st.msg.Nonce(); stNonce < msgNonce { - return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh, - st.msg.From().Hex(), msgNonce, stNonce) - } else if stNonce > msgNonce { - return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow, - st.msg.From().Hex(), msgNonce, stNonce) - } - // Make sure the sender is an EOA - if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) { - return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA, - st.msg.From().Hex(), codeHash) - } - } - // Note: Opera doesn't need to check gasFeeCap >= BaseFee, because it's already checked by epochcheck - return st.buyGas() -} - -func (st *StateTransition) internal() bool { - zeroAddr := common.Address{} - return st.msg.From() == zeroAddr -} - -// TransitionDb will transition the state by applying the current message and -// returning the evm execution result with following fields. -// -// - used gas: -// total gas used (including gas being refunded) -// - returndata: -// the returned data from evm -// - concrete execution error: -// various **EVM** error which aborts the execution, -// e.g. ErrOutOfGas, ErrExecutionReverted -// -// However if any consensus issue encountered, return the error directly with -// nil evm execution result. -func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { - // First check this message satisfies all consensus rules before - // applying the message. The rules include these clauses - // - // 1. the nonce of the message caller is correct - // 2. caller has enough balance to cover transaction fee(gaslimit * gasprice) - // 3. the amount of gas required is available in the block - // 4. the purchased gas is enough to cover intrinsic usage - // 5. there is no overflow when calculating intrinsic gas - - // Note: insufficient balance for **topmost** call isn't a consensus error in Opera, unlike Ethereum - // Such transaction will revert and consume sender's gas - - // Check clauses 1-3, buy gas if everything is correct - if err := st.preCheck(); err != nil { - return nil, err - } - msg := st.msg - sender := vm.AccountRef(msg.From()) - contractCreation := msg.To() == nil - - london := st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) - - // Check clauses 4-5, subtract intrinsic gas if everything is correct - gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation) - if err != nil { - return nil, err - } - if st.gas < gas { - return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas) - } - st.gas -= gas - - // Set up the initial access list. - if rules := st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber); rules.IsBerlin { - st.state.PrepareAccessList(msg.From(), msg.To(), vm.ActivePrecompiles(rules), msg.AccessList()) - } - - var ( - ret []byte - vmerr error // vm errors do not effect consensus and are therefore not assigned to err - ) - if contractCreation { - ret, _, st.gas, vmerr = st.evm.Create(sender, st.data, st.gas, st.value) - } else { - // Increment the nonce for the next transaction - st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1) - ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value) - } - // use 10% of not used gas - if !st.internal() { - st.gas -= st.gas / 10 - } - - if !london { - // Before EIP-3529: refunds were capped to gasUsed / 2 - st.refundGas(params.RefundQuotient) - } else { - // After EIP-3529: refunds are capped to gasUsed / 5 - st.refundGas(params.RefundQuotientEIP3529) - } - - return &ExecutionResult{ - UsedGas: st.gasUsed(), - Err: vmerr, - ReturnData: ret, - }, nil -} - -func (st *StateTransition) refundGas(refundQuotient uint64) { - // Apply refund counter, capped to a refund quotient - refund := st.gasUsed() / refundQuotient - if refund > st.state.GetRefund() { - refund = st.state.GetRefund() - } - st.gas += refund - - // Return wei for remaining gas, exchanged at the original rate. - remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice) - st.state.AddBalance(st.msg.From(), remaining) - - // Also return remaining gas to the block gas counter so it is - // available for the next transaction. - st.gp.AddGas(st.gas) -} - -// gasUsed returns the amount of gas used up by the state transition. -func (st *StateTransition) gasUsed() uint64 { - return st.initialGas - st.gas -} diff --git a/evm/go-x1/evmcore/tx_cacher.go b/evm/go-x1/evmcore/tx_cacher.go deleted file mode 100644 index 933fcec..0000000 --- a/evm/go-x1/evmcore/tx_cacher.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "runtime" - - "github.com/ethereum/go-ethereum/core/types" -) - -// senderCacher is a concurrent transaction sender recoverer and cacher. -var senderCacher = newTxSenderCacher(runtime.NumCPU()) - -// txSenderCacherRequest is a request for recovering transaction senders with a -// specific signature scheme and caching it into the transactions themselves. -// -// The inc field defines the number of transactions to skip after each recovery, -// which is used to feed the same underlying input array to different threads but -// ensure they process the early transactions fast. -type txSenderCacherRequest struct { - signer types.Signer - txs []*types.Transaction - inc int -} - -// txSenderCacher is a helper structure to concurrently ecrecover transaction -// senders from digital signatures on background threads. -type txSenderCacher struct { - threads int - tasks chan *txSenderCacherRequest -} - -// newTxSenderCacher creates a new transaction sender background cacher and starts -// as many processing goroutines as allowed by the GOMAXPROCS on construction. -func newTxSenderCacher(threads int) *txSenderCacher { - cacher := &txSenderCacher{ - tasks: make(chan *txSenderCacherRequest, threads), - threads: threads, - } - for i := 0; i < threads; i++ { - go cacher.cache() - } - return cacher -} - -// cache is an infinite loop, caching transaction senders from various forms of -// data structures. -func (cacher *txSenderCacher) cache() { - for task := range cacher.tasks { - for i := 0; i < len(task.txs); i += task.inc { - types.Sender(task.signer, task.txs[i]) - } - } -} - -// recover recovers the senders from a batch of transactions and caches them -// back into the same data structures. There is no validation being done, nor -// any reaction to invalid signatures. That is up to calling code later. -func (cacher *txSenderCacher) recover(signer types.Signer, txs []*types.Transaction) { - // If there's nothing to recover, abort - if len(txs) == 0 { - return - } - // Ensure we have meaningful task sizes and schedule the recoveries - tasks := cacher.threads - if len(txs) < tasks*4 { - tasks = (len(txs) + 3) / 4 - } - for i := 0; i < tasks; i++ { - cacher.tasks <- &txSenderCacherRequest{ - signer: signer, - txs: txs[i:], - inc: tasks, - } - } -} - -// recoverFromBlocks recovers the senders from a batch of blocks and caches them -// back into the same data structures. There is no validation being done, nor -// any reaction to invalid signatures. That is up to calling code later. -func (cacher *txSenderCacher) recoverFromBlocks(signer types.Signer, blocks []*types.Block) { - count := 0 - for _, block := range blocks { - count += len(block.Transactions()) - } - txs := make([]*types.Transaction, 0, count) - for _, block := range blocks { - txs = append(txs, block.Transactions()...) - } - cacher.recover(signer, txs) -} diff --git a/evm/go-x1/evmcore/tx_journal.go b/evm/go-x1/evmcore/tx_journal.go deleted file mode 100644 index 9e48e78..0000000 --- a/evm/go-x1/evmcore/tx_journal.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "errors" - "io" - "os" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" -) - -// errNoActiveJournal is returned if a transaction is attempted to be inserted -// into the journal, but no such file is currently open. -var errNoActiveJournal = errors.New("no active journal") - -// devNull is a WriteCloser that just discards anything written into it. Its -// goal is to allow the transaction journal to write into a fake journal when -// loading transactions on startup without printing warnings due to no file -// being read for write. -type devNull struct{} - -func (*devNull) Write(p []byte) (n int, err error) { return len(p), nil } -func (*devNull) Close() error { return nil } - -// txJournal is a rotating log of transactions with the aim of storing locally -// created transactions to allow non-executed ones to survive node restarts. -type txJournal struct { - path string // Filesystem path to store the transactions at - writer io.WriteCloser // Output stream to write new transactions into -} - -// newTxJournal creates a new transaction journal to -func newTxJournal(path string) *txJournal { - return &txJournal{ - path: path, - } -} - -// load parses a transaction journal dump from disk, loading its contents into -// the specified pool. -func (journal *txJournal) load(add func([]*types.Transaction) []error) error { - // Skip the parsing if the journal file doesn't exist at all - if _, err := os.Stat(journal.path); os.IsNotExist(err) { - return nil - } - // Open the journal for loading any past transactions - input, err := os.Open(journal.path) - if err != nil { - return err - } - defer input.Close() - - // Temporarily discard any journal additions (don't double add on load) - journal.writer = new(devNull) - defer func() { journal.writer = nil }() - - // Inject all transactions from the journal into the pool - stream := rlp.NewStream(input, 0) - total, dropped := 0, 0 - - // Create a method to load a limited batch of transactions and bump the - // appropriate progress counters. Then use this method to load all the - // journaled transactions in small-ish batches. - loadBatch := func(txs types.Transactions) { - for _, err := range add(txs) { - if err != nil { - log.Debug("Failed to add journaled transaction", "err", err) - dropped++ - } - } - } - var ( - failure error - batch types.Transactions - ) - for { - // Parse the next transaction and terminate on error - tx := new(types.Transaction) - if err = stream.Decode(tx); err != nil { - if err != io.EOF { - failure = err - } - if batch.Len() > 0 { - loadBatch(batch) - } - break - } - // New transaction parsed, queue up for later, import if threshold is reached - total++ - - if batch = append(batch, tx); batch.Len() > 1024 { - loadBatch(batch) - batch = batch[:0] - } - } - log.Info("Loaded local transaction journal", "transactions", total, "dropped", dropped) - - return failure -} - -// insert adds the specified transaction to the local disk journal. -func (journal *txJournal) insert(tx *types.Transaction) error { - if journal.writer == nil { - return errNoActiveJournal - } - if err := rlp.Encode(journal.writer, tx); err != nil { - return err - } - return nil -} - -// rotate regenerates the transaction journal based on the current contents of -// the transaction pool. -func (journal *txJournal) rotate(all map[common.Address]types.Transactions) error { - // Close the current journal (if any is open) - if journal.writer != nil { - if err := journal.writer.Close(); err != nil { - return err - } - journal.writer = nil - } - // Generate a new journal with the contents of the current pool - replacement, err := os.OpenFile(journal.path+".new", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return err - } - journaled := 0 - for _, txs := range all { - for _, tx := range txs { - if err = rlp.Encode(replacement, tx); err != nil { - replacement.Close() - return err - } - } - journaled += len(txs) - } - replacement.Close() - - // Replace the live journal with the newly generated one - if err = os.Rename(journal.path+".new", journal.path); err != nil { - return err - } - sink, err := os.OpenFile(journal.path, os.O_WRONLY|os.O_APPEND, 0644) - if err != nil { - return err - } - journal.writer = sink - log.Info("Regenerated local transaction journal", "transactions", journaled, "accounts", len(all)) - - return nil -} - -// close flushes the transaction journal contents to disk and closes the file. -func (journal *txJournal) close() error { - var err error - - if journal.writer != nil { - err = journal.writer.Close() - journal.writer = nil - } - return err -} diff --git a/evm/go-x1/evmcore/tx_list.go b/evm/go-x1/evmcore/tx_list.go deleted file mode 100644 index eebbb98..0000000 --- a/evm/go-x1/evmcore/tx_list.go +++ /dev/null @@ -1,627 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "container/heap" - "math" - "math/big" - "sort" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -// nonceHeap is a heap.Interface implementation over 64bit unsigned integers for -// retrieving sorted transactions from the possibly gapped future queue. -type nonceHeap []uint64 - -func (h nonceHeap) Len() int { return len(h) } -func (h nonceHeap) Less(i, j int) bool { return h[i] < h[j] } -func (h nonceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } - -func (h *nonceHeap) Push(x interface{}) { - *h = append(*h, x.(uint64)) -} - -func (h *nonceHeap) Pop() interface{} { - old := *h - n := len(old) - x := old[n-1] - *h = old[0 : n-1] - return x -} - -// txSortedMap is a nonce->transaction hash map with a heap based index to allow -// iterating over the contents in a nonce-incrementing way. -type txSortedMap struct { - items map[uint64]*types.Transaction // Hash map storing the transaction data - index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode) - cache types.Transactions // Cache of the transactions already sorted -} - -// newTxSortedMap creates a new nonce-sorted transaction map. -func newTxSortedMap() *txSortedMap { - return &txSortedMap{ - items: make(map[uint64]*types.Transaction), - index: new(nonceHeap), - } -} - -// Get retrieves the current transactions associated with the given nonce. -func (m *txSortedMap) Get(nonce uint64) *types.Transaction { - return m.items[nonce] -} - -// Put inserts a new transaction into the map, also updating the map's nonce -// index. If a transaction already exists with the same nonce, it's overwritten. -func (m *txSortedMap) Put(tx *types.Transaction) { - nonce := tx.Nonce() - if m.items[nonce] == nil { - heap.Push(m.index, nonce) - } - m.items[nonce], m.cache = tx, nil -} - -// Forward removes all transactions from the map with a nonce lower than the -// provided threshold. Every removed transaction is returned for any post-removal -// maintenance. -func (m *txSortedMap) Forward(threshold uint64) types.Transactions { - var removed types.Transactions - - // Pop off heap items until the threshold is reached - for m.index.Len() > 0 && (*m.index)[0] < threshold { - nonce := heap.Pop(m.index).(uint64) - removed = append(removed, m.items[nonce]) - delete(m.items, nonce) - } - // If we had a cached order, shift the front - if m.cache != nil { - m.cache = m.cache[len(removed):] - } - return removed -} - -// Filter iterates over the list of transactions and removes all of them for which -// the specified function evaluates to true. -// Filter, as opposed to 'filter', re-initialises the heap after the operation is done. -// If you want to do several consecutive filterings, it's therefore better to first -// do a .filter(func1) followed by .Filter(func2) or reheap() -func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions { - removed := m.filter(filter) - // If transactions were removed, the heap and cache are ruined - if len(removed) > 0 { - m.reheap() - } - return removed -} - -func (m *txSortedMap) reheap() { - *m.index = make([]uint64, 0, len(m.items)) - for nonce := range m.items { - *m.index = append(*m.index, nonce) - } - heap.Init(m.index) - m.cache = nil -} - -// filter is identical to Filter, but **does not** regenerate the heap. This method -// should only be used if followed immediately by a call to Filter or reheap() -func (m *txSortedMap) filter(filter func(*types.Transaction) bool) types.Transactions { - var removed types.Transactions - - // Collect all the transactions to filter out - for nonce, tx := range m.items { - if filter(tx) { - removed = append(removed, tx) - delete(m.items, nonce) - } - } - if len(removed) > 0 { - m.cache = nil - } - return removed -} - -// Cap places a hard limit on the number of items, returning all transactions -// exceeding that limit. -func (m *txSortedMap) Cap(threshold int) types.Transactions { - // Short circuit if the number of items is under the limit - if len(m.items) <= threshold { - return nil - } - // Otherwise gather and drop the highest nonce'd transactions - var drops types.Transactions - - sort.Sort(*m.index) - for size := len(m.items); size > threshold; size-- { - drops = append(drops, m.items[(*m.index)[size-1]]) - delete(m.items, (*m.index)[size-1]) - } - *m.index = (*m.index)[:threshold] - heap.Init(m.index) - - // If we had a cache, shift the back - if m.cache != nil { - m.cache = m.cache[:len(m.cache)-len(drops)] - } - return drops -} - -// Remove deletes a transaction from the maintained map, returning whether the -// transaction was found. -func (m *txSortedMap) Remove(nonce uint64) bool { - // Short circuit if no transaction is present - _, ok := m.items[nonce] - if !ok { - return false - } - // Otherwise delete the transaction and fix the heap index - for i := 0; i < m.index.Len(); i++ { - if (*m.index)[i] == nonce { - heap.Remove(m.index, i) - break - } - } - delete(m.items, nonce) - m.cache = nil - - return true -} - -// Ready retrieves a sequentially increasing list of transactions starting at the -// provided nonce that is ready for processing. The returned transactions will be -// removed from the list. -// -// Note, all transactions with nonces lower than start will also be returned to -// prevent getting into and invalid state. This is not something that should ever -// happen but better to be self correcting than failing! -func (m *txSortedMap) Ready(start uint64) types.Transactions { - // Short circuit if no transactions are available - if m.index.Len() == 0 || (*m.index)[0] > start { - return nil - } - // Otherwise start accumulating incremental transactions - var ready types.Transactions - for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ { - ready = append(ready, m.items[next]) - delete(m.items, next) - heap.Pop(m.index) - } - m.cache = nil - - return ready -} - -// Len returns the length of the transaction map. -func (m *txSortedMap) Len() int { - return len(m.items) -} - -func (m *txSortedMap) flatten() types.Transactions { - // If the sorting was not cached yet, create and cache it - if m.cache == nil { - m.cache = make(types.Transactions, 0, len(m.items)) - for _, tx := range m.items { - m.cache = append(m.cache, tx) - } - sort.Sort(types.TxByNonce(m.cache)) - } - return m.cache -} - -// Flatten creates a nonce-sorted slice of transactions based on the loosely -// sorted internal representation. The result of the sorting is cached in case -// it's requested again before any modifications are made to the contents. -func (m *txSortedMap) Flatten() types.Transactions { - // Copy the cache to prevent accidental modifications - cache := m.flatten() - txs := make(types.Transactions, len(cache)) - copy(txs, cache) - return txs -} - -// LastElement returns the last element of a flattened list, thus, the -// transaction with the highest nonce -func (m *txSortedMap) LastElement() *types.Transaction { - cache := m.flatten() - return cache[len(cache)-1] -} - -// txList is a "list" of transactions belonging to an account, sorted by account -// nonce. The same type can be used both for storing contiguous transactions for -// the executable/pending queue; and for storing gapped transactions for the non- -// executable/future queue, with minor behavioral changes. -type txList struct { - strict bool // Whether nonces are strictly continuous or not - txs *txSortedMap // Heap indexed sorted hash map of the transactions - - costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance) - gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit) -} - -// newTxList create a new transaction list for maintaining nonce-indexable fast, -// gapped, sortable transaction lists. -func newTxList(strict bool) *txList { - return &txList{ - strict: strict, - txs: newTxSortedMap(), - costcap: new(big.Int), - } -} - -// Overlaps returns whether the transaction specified has the same nonce as one -// already contained within the list. -func (l *txList) Overlaps(tx *types.Transaction) bool { - return l.txs.Get(tx.Nonce()) != nil -} - -// Add tries to insert a new transaction into the list, returning whether the -// transaction was accepted, and if yes, any previous transaction it replaced. -// -// If the new transaction is accepted into the list, the lists' cost and gas -// thresholds are also potentially updated. -func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) { - // If there's an older better transaction, abort - old := l.txs.Get(tx.Nonce()) - if old != nil { - if old.GasFeeCapCmp(tx) >= 0 || old.GasTipCapCmp(tx) >= 0 { - return false, nil - } - // thresholdFeeCap = oldFC * (100 + priceBump) / 100 - a := big.NewInt(100 + int64(priceBump)) - aFeeCap := new(big.Int).Mul(a, old.GasFeeCap()) - aTip := a.Mul(a, old.GasTipCap()) - - // thresholdTip = oldTip * (100 + priceBump) / 100 - b := big.NewInt(100) - thresholdFeeCap := aFeeCap.Div(aFeeCap, b) - thresholdTip := aTip.Div(aTip, b) - - // Have to ensure that either the new fee cap or tip is higher than the - // old ones as well as checking the percentage threshold to ensure that - // this is accurate for low (Wei-level) gas price replacements - if tx.GasFeeCapIntCmp(thresholdFeeCap) < 0 || tx.GasTipCapIntCmp(thresholdTip) < 0 { - return false, nil - } - } - // Otherwise overwrite the old transaction with the current one - l.txs.Put(tx) - if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 { - l.costcap = cost - } - if gas := tx.Gas(); l.gascap < gas { - l.gascap = gas - } - return true, old -} - -// Forward removes all transactions from the list with a nonce lower than the -// provided threshold. Every removed transaction is returned for any post-removal -// maintenance. -func (l *txList) Forward(threshold uint64) types.Transactions { - return l.txs.Forward(threshold) -} - -// Filter removes all transactions from the list with a cost or gas limit higher -// than the provided thresholds. Every removed transaction is returned for any -// post-removal maintenance. Strict-mode invalidated transactions are also -// returned. -// -// This method uses the cached costcap and gascap to quickly decide if there's even -// a point in calculating all the costs or if the balance covers all. If the threshold -// is lower than the costgas cap, the caps will be reset to a new high after removing -// the newly invalidated transactions. -func (l *txList) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions, types.Transactions) { - // If all transactions are below the threshold, short circuit - if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit { - return nil, nil - } - l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds - l.gascap = gasLimit - - // Filter out all the transactions above the account's funds - removed := l.txs.Filter(func(tx *types.Transaction) bool { - return tx.Gas() > gasLimit || tx.Cost().Cmp(costLimit) > 0 - }) - - if len(removed) == 0 { - return nil, nil - } - var invalids types.Transactions - // If the list was strict, filter anything above the lowest nonce - if l.strict { - lowest := uint64(math.MaxUint64) - for _, tx := range removed { - if nonce := tx.Nonce(); lowest > nonce { - lowest = nonce - } - } - invalids = l.txs.filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest }) - } - l.txs.reheap() - return removed, invalids -} - -// Cap places a hard limit on the number of items, returning all transactions -// exceeding that limit. -func (l *txList) Cap(threshold int) types.Transactions { - return l.txs.Cap(threshold) -} - -// Remove deletes a transaction from the maintained list, returning whether the -// transaction was found, and also returning any transaction invalidated due to -// the deletion (strict mode only). -func (l *txList) Remove(tx *types.Transaction) (bool, types.Transactions) { - // Remove the transaction from the set - nonce := tx.Nonce() - if removed := l.txs.Remove(nonce); !removed { - return false, nil - } - // In strict mode, filter out non-executable transactions - if l.strict { - return true, l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > nonce }) - } - return true, nil -} - -// Ready retrieves a sequentially increasing list of transactions starting at the -// provided nonce that is ready for processing. The returned transactions will be -// removed from the list. -// -// Note, all transactions with nonces lower than start will also be returned to -// prevent getting into and invalid state. This is not something that should ever -// happen but better to be self correcting than failing! -func (l *txList) Ready(start uint64) types.Transactions { - return l.txs.Ready(start) -} - -// Len returns the length of the transaction list. -func (l *txList) Len() int { - return l.txs.Len() -} - -// Empty returns whether the list of transactions is empty or not. -func (l *txList) Empty() bool { - return l.Len() == 0 -} - -// Flatten creates a nonce-sorted slice of transactions based on the loosely -// sorted internal representation. The result of the sorting is cached in case -// it's requested again before any modifications are made to the contents. -func (l *txList) Flatten() types.Transactions { - return l.txs.Flatten() -} - -// LastElement returns the last element of a flattened list, thus, the -// transaction with the highest nonce -func (l *txList) LastElement() *types.Transaction { - return l.txs.LastElement() -} - -// priceHeap is a heap.Interface implementation over transactions for retrieving -// price-sorted transactions to discard when the pool fills up. If baseFee is set -// then the heap is sorted based on the effective tip based on the given base fee. -// If baseFee is nil then the sorting is based on gasFeeCap. -type priceHeap struct { - baseFee *big.Int // heap should always be re-sorted after baseFee is changed - list []*types.Transaction -} - -func (h *priceHeap) Len() int { return len(h.list) } -func (h *priceHeap) Swap(i, j int) { h.list[i], h.list[j] = h.list[j], h.list[i] } - -func (h *priceHeap) Less(i, j int) bool { - switch h.cmp(h.list[i], h.list[j]) { - case -1: - return true - case 1: - return false - default: - return h.list[i].Nonce() > h.list[j].Nonce() - } -} - -func (h *priceHeap) cmp(a, b *types.Transaction) int { - if h.baseFee != nil { - // Compare effective tips if baseFee is specified - if c := a.EffectiveGasTipCmp(b, h.baseFee); c != 0 { - return c - } - } - // Compare fee caps if baseFee is not specified or effective tips are equal - if c := a.GasFeeCapCmp(b); c != 0 { - return c - } - // Compare tips if effective tips and fee caps are equal - return a.GasTipCapCmp(b) -} - -func (h *priceHeap) Push(x interface{}) { - tx := x.(*types.Transaction) - h.list = append(h.list, tx) -} - -func (h *priceHeap) Pop() interface{} { - old := h.list - n := len(old) - x := old[n-1] - old[n-1] = nil - h.list = old[0 : n-1] - return x -} - -// txPricedList is a price-sorted heap to allow operating on transactions pool -// contents in a price-incrementing way. It's built opon the all transactions -// in txpool but only interested in the remote part. It means only remote transactions -// will be considered for tracking, sorting, eviction, etc. -// -// Two heaps are used for sorting: the urgent heap (based on effective tip in the next -// block) and the floating heap (based on gasFeeCap). Always the bigger heap is chosen for -// eviction. Transactions evicted from the urgent heap are first demoted into the floating heap. -// In some cases (during a congestion, when blocks are full) the urgent heap can provide -// better candidates for inclusion while in other cases (at the top of the baseFee peak) -// the floating heap is better. When baseFee is decreasing they behave similarly. -type txPricedList struct { - all *txLookup // Pointer to the map of all transactions - urgent, floating priceHeap // Heaps of prices of all the stored **remote** transactions - stales int // Number of stale price points to (re-heap trigger) -} - -const ( - // urgentRatio : floatingRatio is the capacity ratio of the two queues - urgentRatio = 4 - floatingRatio = 1 -) - -// newTxPricedList creates a new price-sorted transaction heap. -func newTxPricedList(all *txLookup) *txPricedList { - return &txPricedList{ - all: all, - } -} - -// Put inserts a new transaction into the heap. -func (l *txPricedList) Put(tx *types.Transaction, local bool) { - if local { - return - } - // Insert every new transaction to the urgent heap first; Discard will balance the heaps - heap.Push(&l.urgent, tx) -} - -// Removed notifies the prices transaction list that an old transaction dropped -// from the pool. The list will just keep a counter of stale objects and update -// the heap if a large enough ratio of transactions go stale. -func (l *txPricedList) Removed(count int) { - // Bump the stale counter, but exit if still too low (< 25%) - l.stales += count - if l.stales <= (len(l.urgent.list)+len(l.floating.list))/4 { - return - } - // Seems we've reached a critical number of stale transactions, reheap - l.Reheap() -} - -// Underpriced checks whether a transaction is cheaper than (or as cheap as) the -// lowest priced (remote) transaction currently being tracked. -func (l *txPricedList) Underpriced(tx *types.Transaction) bool { - // Note: with two queues, being underpriced is defined as being worse than the worst item - // in all non-empty queues if there is any. If both queues are empty then nothing is underpriced. - return (l.underpricedFor(&l.urgent, tx) || len(l.urgent.list) == 0) && - (l.underpricedFor(&l.floating, tx) || len(l.floating.list) == 0) && - (len(l.urgent.list) != 0 || len(l.floating.list) != 0) -} - -// underpricedFor checks whether a transaction is cheaper than (or as cheap as) the -// lowest priced (remote) transaction in the given heap. -func (l *txPricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool { - // Discard stale price points if found at the heap start - for len(h.list) > 0 { - head := h.list[0] - if l.all.GetRemote(head.Hash()) == nil { // Removed or migrated - l.stales-- - heap.Pop(h) - continue - } - break - } - // Check if the transaction is underpriced or not - if len(h.list) == 0 { - return false // There is no remote transaction at all. - } - // If the remote transaction is even cheaper than the - // cheapest one tracked locally, reject it. - return h.cmp(h.list[0], tx) >= 0 -} - -// Discard finds a number of most underpriced transactions, removes them from the -// priced list and returns them for further removal from the entire pool. -// -// Note local transaction won't be considered for eviction. -func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool) { - drop := make(types.Transactions, 0, slots) // Remote underpriced transactions to drop - for slots > 0 { - if len(l.urgent.list)*floatingRatio > len(l.floating.list)*urgentRatio || floatingRatio == 0 { - // Discard stale transactions if found during cleanup - tx := heap.Pop(&l.urgent).(*types.Transaction) - if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated - l.stales-- - continue - } - // Non stale transaction found, move to floating heap - heap.Push(&l.floating, tx) - } else { - if len(l.floating.list) == 0 { - // Stop if both heaps are empty - break - } - // Discard stale transactions if found during cleanup - tx := heap.Pop(&l.floating).(*types.Transaction) - if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated - l.stales-- - continue - } - // Non stale transaction found, discard it - drop = append(drop, tx) - slots -= numSlots(tx) - } - } - // If we still can't make enough room for the new transaction - if slots > 0 && !force { - for _, tx := range drop { - heap.Push(&l.urgent, tx) - } - return nil, false - } - return drop, true -} - -// Reheap forcibly rebuilds the heap based on the current remote transaction set. -func (l *txPricedList) Reheap() { - start := time.Now() - l.stales = 0 - l.urgent.list = make([]*types.Transaction, 0, l.all.RemoteCount()) - l.all.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool { - l.urgent.list = append(l.urgent.list, tx) - return true - }, false, true) // Only iterate remotes - heap.Init(&l.urgent) - - // balance out the two heaps by moving the worse half of transactions into the - // floating heap - // Note: Discard would also do this before the first eviction but Reheap can do - // is more efficiently. Also, Underpriced would work suboptimally the first time - // if the floating queue was empty. - floatingCount := len(l.urgent.list) * floatingRatio / (urgentRatio + floatingRatio) - l.floating.list = make([]*types.Transaction, floatingCount) - for i := 0; i < floatingCount; i++ { - l.floating.list[i] = heap.Pop(&l.urgent).(*types.Transaction) - } - heap.Init(&l.floating) - reheapTimer.Update(time.Since(start)) -} - -// SetBaseFee updates the base fee and triggers a re-heap. Note that Removed is not -// necessary to call right before SetBaseFee when processing a new block. -func (l *txPricedList) SetBaseFee(baseFee *big.Int) { - if l.urgent.baseFee == nil || l.urgent.baseFee.Cmp(baseFee) != 0 { - l.urgent.baseFee = baseFee - l.Reheap() - } -} diff --git a/evm/go-x1/evmcore/tx_list_test.go b/evm/go-x1/evmcore/tx_list_test.go deleted file mode 100644 index c1fbfe6..0000000 --- a/evm/go-x1/evmcore/tx_list_test.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "math/big" - "math/rand" - "testing" - - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" -) - -// Tests that transactions can be added to strict lists and list contents and -// nonce boundaries are correctly maintained. -func TestStrictTxListAdd(t *testing.T) { - // Generate a list of transactions to insert - key, _ := crypto.GenerateKey() - - txs := make(types.Transactions, 1024) - for i := 0; i < len(txs); i++ { - txs[i] = transaction(uint64(i), 0, key) - } - // Insert the transactions in a random order - list := newTxList(true) - for _, v := range rand.Perm(len(txs)) { - list.Add(txs[v], DefaultTxPoolConfig.PriceBump) - } - // Verify internal state - if len(list.txs.items) != len(txs) { - t.Errorf("transaction count mismatch: have %d, want %d", len(list.txs.items), len(txs)) - } - for i, tx := range txs { - if list.txs.items[tx.Nonce()] != tx { - t.Errorf("item %d: transaction mismatch: have %v, want %v", i, list.txs.items[tx.Nonce()], tx) - } - } -} - -func BenchmarkTxListAdd(t *testing.B) { - // Generate a list of transactions to insert - key, _ := crypto.GenerateKey() - - txs := make(types.Transactions, 100000) - for i := 0; i < len(txs); i++ { - txs[i] = transaction(uint64(i), 0, key) - } - // Insert the transactions in a random order - list := newTxList(true) - priceLimit := big.NewInt(int64(DefaultTxPoolConfig.PriceLimit)) - t.ResetTimer() - for _, v := range rand.Perm(len(txs)) { - list.Add(txs[v], DefaultTxPoolConfig.PriceBump) - list.Filter(priceLimit, DefaultTxPoolConfig.PriceBump) - } -} diff --git a/evm/go-x1/evmcore/tx_noncer.go b/evm/go-x1/evmcore/tx_noncer.go deleted file mode 100644 index ef549ed..0000000 --- a/evm/go-x1/evmcore/tx_noncer.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "sync" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" -) - -// txNoncer is a tiny virtual state database to manage the executable nonces of -// accounts in the pool, falling back to reading from a real state database if -// an account is unknown. -type txNoncer struct { - fallback *state.StateDB - nonces map[common.Address]uint64 - lock sync.Mutex -} - -// newTxNoncer creates a new virtual state database to track the pool nonces. -func newTxNoncer(statedb *state.StateDB) *txNoncer { - return &txNoncer{ - fallback: statedb.Copy(), - nonces: make(map[common.Address]uint64), - } -} - -// get returns the current nonce of an account, falling back to a real state -// database if the account is unknown. -func (txn *txNoncer) get(addr common.Address) uint64 { - // We use mutex for get operation is the underlying - // state will mutate db even for read access. - txn.lock.Lock() - defer txn.lock.Unlock() - - if _, ok := txn.nonces[addr]; !ok { - txn.nonces[addr] = txn.fallback.GetNonce(addr) - } - return txn.nonces[addr] -} - -// set inserts a new virtual nonce into the virtual state database to be returned -// whenever the pool requests it instead of reaching into the real state database. -func (txn *txNoncer) set(addr common.Address, nonce uint64) { - txn.lock.Lock() - defer txn.lock.Unlock() - - txn.nonces[addr] = nonce -} - -// setIfLower updates a new virtual nonce into the virtual state database if the -// the new one is lower. -func (txn *txNoncer) setIfLower(addr common.Address, nonce uint64) { - txn.lock.Lock() - defer txn.lock.Unlock() - - if _, ok := txn.nonces[addr]; !ok { - txn.nonces[addr] = txn.fallback.GetNonce(addr) - } - if txn.nonces[addr] <= nonce { - return - } - txn.nonces[addr] = nonce -} diff --git a/evm/go-x1/evmcore/tx_pool.go b/evm/go-x1/evmcore/tx_pool.go deleted file mode 100644 index f994fb6..0000000 --- a/evm/go-x1/evmcore/tx_pool.go +++ /dev/null @@ -1,1887 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "errors" - "math" - "math/big" - "math/rand" - "sort" - "sync" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/prque" - "github.com/ethereum/go-ethereum/consensus/misc" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - notify "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/utils/signers/gsignercache" - "github.com/Fantom-foundation/go-opera/utils/txtime" -) - -const ( - // chainHeadChanSize is the size of channel listening to ChainHeadNotify. - chainHeadChanSize = 10 - - // txSlotSize is used to calculate how many data slots a single transaction - // takes up based on its size. The slots are used as DoS protection, ensuring - // that validating a new transaction remains a constant operation (in reality - // O(maxslots), where max slots are 4 currently). - txSlotSize = 32 * 1024 - - // txMaxSize is the maximum size a single transaction can have. This field has - // non-trivial consequences: larger transactions are significantly harder and - // more expensive to propagate; larger transactions also take more resources - // to validate whether they fit into the pool or not. - txMaxSize = 4 * txSlotSize // 128KB -) - -var ( - // ErrAlreadyKnown is returned if the transactions is already contained - // within the pool. - ErrAlreadyKnown = errors.New("already known") - - // ErrInvalidSender is returned if the transaction contains an invalid signature. - ErrInvalidSender = errors.New("invalid sender") - - // ErrUnderpriced is returned if a transaction's gas price is below the minimum - // configured for the transaction pool. - ErrUnderpriced = errors.New("transaction underpriced") - - // ErrTxPoolOverflow is returned if the transaction pool is full and can't accpet - // another remote transaction. - ErrTxPoolOverflow = errors.New("txpool is full") - - // ErrReplaceUnderpriced is returned if a transaction is attempted to be replaced - // with a different one without the required price bump. - ErrReplaceUnderpriced = errors.New("replacement transaction underpriced") - - // ErrGasLimit is returned if a transaction's requested gas limit exceeds the - // maximum allowance of the current block. - ErrGasLimit = errors.New("exceeds block gas limit") - - // ErrNegativeValue is a sanity error to ensure no one is able to specify a - // transaction with a negative value. - ErrNegativeValue = errors.New("negative value") - - // ErrOversizedData is returned if the input data of a transaction is greater - // than some meaningful limit a user might use. This is not a consensus error - // making the transaction invalid, rather a DOS protection. - ErrOversizedData = errors.New("oversized data") -) - -var ( - evictionInterval = time.Minute // Time interval to check for evictable transactions - statsReportInterval = 8 * time.Second // Time interval to report transaction pool stats -) - -var ( - // Metrics for the pending pool - pendingDiscardMeter = metrics.GetOrRegisterMeter("txpool/pending/discard", nil) - pendingReplaceMeter = metrics.GetOrRegisterMeter("txpool/pending/replace", nil) - pendingRateLimitMeter = metrics.GetOrRegisterMeter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting - pendingNofundsMeter = metrics.GetOrRegisterMeter("txpool/pending/nofunds", nil) // Dropped due to out-of-funds - - // Metrics for the queued pool - queuedDiscardMeter = metrics.GetOrRegisterMeter("txpool/queued/discard", nil) - queuedReplaceMeter = metrics.GetOrRegisterMeter("txpool/queued/replace", nil) - queuedRateLimitMeter = metrics.GetOrRegisterMeter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting - queuedNofundsMeter = metrics.GetOrRegisterMeter("txpool/queued/nofunds", nil) // Dropped due to out-of-funds - queuedEvictionMeter = metrics.GetOrRegisterMeter("txpool/queued/eviction", nil) // Dropped due to lifetime - - // General tx metrics - validTxMeter = metrics.GetOrRegisterMeter("txpool/valid", nil) - invalidTxMeter = metrics.GetOrRegisterMeter("txpool/invalid", nil) - underpricedTxMeter = metrics.GetOrRegisterMeter("txpool/underpriced", nil) - overflowedTxMeter = metrics.GetOrRegisterMeter("txpool/overflowed", nil) - - pendingGauge = metrics.GetOrRegisterGauge("txpool/pending", nil) - queuedGauge = metrics.GetOrRegisterGauge("txpool/queued", nil) - localGauge = metrics.GetOrRegisterGauge("txpool/local", nil) - slotsGauge = metrics.GetOrRegisterGauge("txpool/slots", nil) - - reheapTimer = metrics.GetOrRegisterTimer("txpool/reheap", nil) -) - -// TxStatus is the current status of a transaction as seen by the pool. -type TxStatus uint - -const ( - TxStatusUnknown TxStatus = iota - TxStatusQueued - TxStatusPending - TxStatusIncluded -) - -// StateReader provides the state of blockchain and current gas limit to do -// some pre checks in tx pool and event subscribers. -type StateReader interface { - CurrentBlock() *EvmBlock - GetBlock(hash common.Hash, number uint64) *EvmBlock - StateAt(root common.Hash) (*state.StateDB, error) - MinGasPrice() *big.Int - EffectiveMinTip() *big.Int - MaxGasLimit() uint64 - SubscribeNewBlock(ch chan<- ChainHeadNotify) notify.Subscription - Config() *params.ChainConfig -} - -// TxPoolConfig are the configuration parameters of the transaction pool. -type TxPoolConfig struct { - Locals []common.Address // Addresses that should be treated by default as local - NoLocals bool // Whether local transaction handling should be disabled - Journal string // Journal of local transactions to survive node restarts - Rejournal time.Duration // Time interval to regenerate the local transaction journal - - PriceLimit uint64 // Minimum gas tip to enforce for acceptance into the pool - PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce) - - AccountSlots uint64 // Number of executable transaction slots guaranteed per account - GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts - AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account - GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts - - Lifetime time.Duration // Maximum amount of time non-executable transaction are queued -} - -// DefaultTxPoolConfig contains the default configurations for the transaction -// pool. -var DefaultTxPoolConfig = TxPoolConfig{ - Journal: "transactions.rlp", - Rejournal: time.Hour, - - PriceLimit: 0, - PriceBump: 10, - - AccountSlots: 16, - GlobalSlots: 1024 + 256, // urgent + floating queue capacity with 4:1 ratio - AccountQueue: 32, - GlobalQueue: 256, - - Lifetime: 3 * time.Hour, -} - -// sanitize checks the provided user configurations and changes anything that's -// unreasonable or unworkable. -func (config *TxPoolConfig) sanitize() TxPoolConfig { - conf := *config - if conf.Rejournal < time.Second { - log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second) - conf.Rejournal = time.Second - } - if conf.PriceBump < 1 { - log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump) - conf.PriceBump = DefaultTxPoolConfig.PriceBump - } - if conf.AccountSlots < 1 { - log.Warn("Sanitizing invalid txpool account slots", "provided", conf.AccountSlots, "updated", DefaultTxPoolConfig.AccountSlots) - conf.AccountSlots = DefaultTxPoolConfig.AccountSlots - } - if conf.GlobalSlots < 1 { - log.Warn("Sanitizing invalid txpool global slots", "provided", conf.GlobalSlots, "updated", DefaultTxPoolConfig.GlobalSlots) - conf.GlobalSlots = DefaultTxPoolConfig.GlobalSlots - } - if conf.AccountQueue < 1 { - log.Warn("Sanitizing invalid txpool account queue", "provided", conf.AccountQueue, "updated", DefaultTxPoolConfig.AccountQueue) - conf.AccountQueue = DefaultTxPoolConfig.AccountQueue - } - if conf.GlobalQueue < 1 { - log.Warn("Sanitizing invalid txpool global queue", "provided", conf.GlobalQueue, "updated", DefaultTxPoolConfig.GlobalQueue) - conf.GlobalQueue = DefaultTxPoolConfig.GlobalQueue - } - if conf.Lifetime < 1 { - log.Warn("Sanitizing invalid txpool lifetime", "provided", conf.Lifetime, "updated", DefaultTxPoolConfig.Lifetime) - conf.Lifetime = DefaultTxPoolConfig.Lifetime - } - return conf -} - -// TxPool contains all currently known transactions. Transactions -// enter the pool when they are received from the network or submitted -// locally. They exit the pool when they are included in the blockchain. -// -// The pool separates processable transactions (which can be applied to the -// current state) and future transactions. Transactions move between those -// two states over time as they are received and processed. -type TxPool struct { - config TxPoolConfig - chainconfig *params.ChainConfig - chain StateReader - gasPrice *big.Int - txFeed notify.Feed - scope notify.SubscriptionScope - signer types.Signer - mu sync.RWMutex - - istanbul bool // Fork indicator whether we are in the istanbul stage. - eip2718 bool // Fork indicator whether we are using EIP-2718 type transactions. - eip1559 bool // Fork indicator whether we are using EIP-1559 type transactions. - - currentState *state.StateDB // Current state in the blockchain head - pendingNonces *txNoncer // Pending state tracking virtual nonces - currentMaxGas uint64 // Current gas limit for transaction caps - - locals *accountSet // Set of local transaction to exempt from eviction rules - journal *txJournal // Journal of local transaction to back up to disk - - pending map[common.Address]*txList // All currently processable transactions - queue map[common.Address]*txList // Queued but non-processable transactions - beats map[common.Address]time.Time // Last heartbeat from each known account - all *txLookup // All transactions to allow lookups - priced *txPricedList // All transactions sorted by price - - chainHeadCh chan ChainHeadNotify - chainHeadSub notify.Subscription - reqResetCh chan *txpoolResetRequest - reqPromoteCh chan *accountSet - queueTxEventCh chan *types.Transaction - reorgDoneCh chan chan struct{} - reorgShutdownCh chan struct{} // requests shutdown of scheduleReorgLoop - wg sync.WaitGroup // tracks loop, scheduleReorgLoop -} - -type txpoolResetRequest struct { - oldHead, newHead *EvmHeader -} - -// NewTxPool creates a new transaction pool to gather, sort and filter inbound -// transactions from the network. -func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain StateReader) *TxPool { - // Sanitize the input to ensure no vulnerable gas prices are set - config = (&config).sanitize() - - // Create the transaction pool with its initial settings - pool := &TxPool{ - config: config, - chainconfig: chainconfig, - chain: chain, - signer: gsignercache.Wrap(types.LatestSignerForChainID(chainconfig.ChainID)), - pending: make(map[common.Address]*txList), - queue: make(map[common.Address]*txList), - beats: make(map[common.Address]time.Time), - all: newTxLookup(), - chainHeadCh: make(chan ChainHeadNotify, chainHeadChanSize), - reqResetCh: make(chan *txpoolResetRequest), - reqPromoteCh: make(chan *accountSet), - queueTxEventCh: make(chan *types.Transaction), - reorgDoneCh: make(chan chan struct{}), - reorgShutdownCh: make(chan struct{}), - gasPrice: new(big.Int).SetUint64(config.PriceLimit), - } - pool.locals = newAccountSet(pool.signer) - for _, addr := range config.Locals { - log.Info("Setting new local account", "address", addr) - pool.locals.add(addr) - } - pool.priced = newTxPricedList(pool.all) - pool.reset(nil, chain.CurrentBlock().Header()) - - // Start the reorg loop early so it can handle requests generated during journal loading. - pool.wg.Add(1) - go pool.scheduleReorgLoop() - - // If local transactions and journaling is enabled, load from disk - if !config.NoLocals && config.Journal != "" { - pool.journal = newTxJournal(config.Journal) - - if err := pool.journal.load(pool.AddLocals); err != nil { - log.Warn("Failed to load transaction journal", "err", err) - } - if err := pool.journal.rotate(pool.local()); err != nil { - log.Warn("Failed to rotate transaction journal", "err", err) - } - } - - // Subscribe events from blockchain and start the main event loop. - pool.chainHeadSub = pool.chain.SubscribeNewBlock(pool.chainHeadCh) - pool.wg.Add(1) - go pool.loop() - - return pool -} - -// loop is the transaction pool's main event loop, waiting for and reacting to -// outside blockchain events as well as for various reporting and transaction -// eviction events. -func (pool *TxPool) loop() { - defer pool.wg.Done() - - var ( - prevPending, prevQueued, prevStales int - // Start the stats reporting and transaction eviction tickers - report = time.NewTicker(statsReportInterval) - evict = time.NewTicker(evictionInterval) - journal = time.NewTicker(pool.config.Rejournal) - // Track the previous head headers for transaction reorgs - head = pool.chain.CurrentBlock() - ) - defer report.Stop() - defer evict.Stop() - defer journal.Stop() - - for { - select { - // Handle ChainHeadNotify - case ev := <-pool.chainHeadCh: - if ev.Block != nil { - pool.requestReset(head.Header(), ev.Block.Header()) - head = ev.Block - } - - // System shutdown. - case <-pool.chainHeadSub.Err(): - close(pool.reorgShutdownCh) - return - - // Handle stats reporting ticks - case <-report.C: - pool.mu.RLock() - pending, queued := pool.stats() - stales := pool.priced.stales - pool.mu.RUnlock() - - if pending != prevPending || queued != prevQueued || stales != prevStales { - log.Debug("Transaction pool status report", "executable", pending, "queued", queued, "stales", stales) - prevPending, prevQueued, prevStales = pending, queued, stales - } - - // Handle inactive account transaction eviction - case <-evict.C: - pool.mu.Lock() - for addr := range pool.queue { - // Skip local transactions from the eviction mechanism - if pool.locals.contains(addr) { - continue - } - // Any non-locals old enough should be removed - if time.Since(pool.beats[addr]) > pool.config.Lifetime { - list := pool.queue[addr].Flatten() - for _, tx := range list { - pool.removeTx(tx.Hash(), true) - } - queuedEvictionMeter.Mark(int64(len(list))) - } - } - pool.mu.Unlock() - - // Handle local transaction journal rotation - case <-journal.C: - if pool.journal != nil { - pool.mu.Lock() - if err := pool.journal.rotate(pool.local()); err != nil { - log.Warn("Failed to rotate local tx journal", "err", err) - } - pool.mu.Unlock() - } - } - } -} - -// Stop terminates the transaction pool. -func (pool *TxPool) Stop() { - // Unsubscribe all subscriptions registered from txpool - pool.scope.Close() - - // Unsubscribe subscriptions registered from blockchain - pool.chainHeadSub.Unsubscribe() - pool.wg.Wait() - - if pool.journal != nil { - pool.journal.close() - } - log.Info("Transaction pool stopped") -} - -// SubscribeNewTxsNotify registers a subscription of NewTxsNotify and -// starts sending event to the given channel. -func (pool *TxPool) SubscribeNewTxsNotify(ch chan<- NewTxsNotify) notify.Subscription { - return pool.scope.Track(pool.txFeed.Subscribe(ch)) -} - -// GasPrice returns the current gas price enforced by the transaction pool. -func (pool *TxPool) GasPrice() *big.Int { - pool.mu.RLock() - defer pool.mu.RUnlock() - - return new(big.Int).Set(pool.gasPrice) -} - -// SetGasPrice updates the minimum price required by the transaction pool for a -// new transaction, and drops all transactions below this threshold. -func (pool *TxPool) SetGasPrice(price *big.Int) { - pool.mu.Lock() - defer pool.mu.Unlock() - - old := pool.gasPrice - pool.gasPrice = price - // if the min miner fee increased, remove transactions below the new threshold - if price.Cmp(old) > 0 { - // pool.priced is sorted by GasFeeCap, so we have to iterate through pool.all instead - drop := pool.all.RemotesBelowTip(price) - for _, tx := range drop { - pool.removeTx(tx.Hash(), false) - } - pool.priced.Removed(len(drop)) - } - - log.Info("Transaction pool price threshold updated", "price", price) -} - -// Nonce returns the next nonce of an account, with all transactions executable -// by the pool already applied on top. -func (pool *TxPool) Nonce(addr common.Address) uint64 { - pool.mu.RLock() - defer pool.mu.RUnlock() - - return pool.pendingNonces.get(addr) -} - -// Stats retrieves the current pool stats, namely the number of pending and the -// number of queued (non-executable) transactions. -func (pool *TxPool) Stats() (int, int) { - pool.mu.RLock() - defer pool.mu.RUnlock() - - return pool.stats() -} - -// Count returns the total number of transactions -func (pool *TxPool) Count() int { - pool.mu.RLock() - defer pool.mu.RUnlock() - - return pool.all.Count() -} - -// stats retrieves the current pool stats, namely the number of pending and the -// number of queued (non-executable) transactions. -func (pool *TxPool) stats() (int, int) { - pending := 0 - for _, list := range pool.pending { - pending += list.Len() - } - queued := 0 - for _, list := range pool.queue { - queued += list.Len() - } - return pending, queued -} - -// Content retrieves the data content of the transaction pool, returning all the -// pending as well as queued transactions, grouped by account and sorted by nonce. -func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { - pool.mu.Lock() - defer pool.mu.Unlock() - - pending := make(map[common.Address]types.Transactions) - for addr, list := range pool.pending { - pending[addr] = list.Flatten() - } - queued := make(map[common.Address]types.Transactions) - for addr, list := range pool.queue { - queued[addr] = list.Flatten() - } - return pending, queued -} - -// ContentFrom retrieves the data content of the transaction pool, returning the -// pending as well as queued transactions of this address, grouped by nonce. -func (pool *TxPool) ContentFrom(addr common.Address) (types.Transactions, types.Transactions) { - pool.mu.RLock() - defer pool.mu.RUnlock() - - var pending types.Transactions - if list, ok := pool.pending[addr]; ok { - pending = list.Flatten() - } - var queued types.Transactions - if list, ok := pool.queue[addr]; ok { - queued = list.Flatten() - } - return pending, queued -} - -// Pending retrieves all currently processable transactions, grouped by origin -// account and sorted by nonce. The returned transaction set is a copy and can be -// freely modified by calling code. -// -// The enforceTips parameter can be used to do an extra filtering on the pending -// transactions and only return those whose **effective** tip is large enough in -// the next pending execution environment. -func (pool *TxPool) Pending(enforceTips bool) (map[common.Address]types.Transactions, error) { - pool.mu.Lock() - defer pool.mu.Unlock() - - pending := make(map[common.Address]types.Transactions) - for addr, list := range pool.pending { - txs := list.Flatten() - - // If the miner requests tip enforcement, cap the lists now - if enforceTips && !pool.locals.contains(addr) { - for i, tx := range txs { - if tx.EffectiveGasTipIntCmp(pool.gasPrice, pool.priced.urgent.baseFee) < 0 { - txs = txs[:i] - break - } - } - } - if len(txs) > 0 { - pending[addr] = txs - } - } - return pending, nil -} - -func (pool *TxPool) SampleHashes(max int) []common.Hash { - return pool.all.SampleHashes(max) -} - -// Locals retrieves the accounts currently considered local by the pool. -func (pool *TxPool) Locals() []common.Address { - pool.mu.Lock() - defer pool.mu.Unlock() - - return pool.locals.flatten() -} - -// local retrieves all currently known local transactions, grouped by origin -// account and sorted by nonce. The returned transaction set is a copy and can be -// freely modified by calling code. -func (pool *TxPool) local() map[common.Address]types.Transactions { - txs := make(map[common.Address]types.Transactions) - for addr := range pool.locals.accounts { - if pending := pool.pending[addr]; pending != nil { - txs[addr] = append(txs[addr], pending.Flatten()...) - } - if queued := pool.queue[addr]; queued != nil { - txs[addr] = append(txs[addr], queued.Flatten()...) - } - } - return txs -} - -// validateTx checks whether a transaction is valid according to the consensus -// rules and adheres to some heuristic limits of the local node (price and size). -func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { - // Accept only legacy transactions until EIP-2718/2930 activates. - if !pool.eip2718 && tx.Type() != types.LegacyTxType { - return ErrTxTypeNotSupported - } - // Reject dynamic fee transactions until EIP-1559 activates. - if !pool.eip1559 && tx.Type() == types.DynamicFeeTxType { - return ErrTxTypeNotSupported - } - // Reject transactions over defined size to prevent DOS attacks - if uint64(tx.Size()) > txMaxSize { - return ErrOversizedData - } - // Transactions can't be negative. This may never happen using RLP decoded - // transactions but may occur if you create a transaction using the RPC. - if tx.Value().Sign() < 0 { - return ErrNegativeValue - } - // Ensure the transaction doesn't exceed the current block limit gas. - if pool.currentMaxGas < tx.Gas() { - return ErrGasLimit - } - // Sanity check for extremely large numbers - if tx.GasFeeCap().BitLen() > 256 { - return ErrFeeCapVeryHigh - } - if tx.GasTipCap().BitLen() > 256 { - return ErrTipVeryHigh - } - // Ensure gasFeeCap is greater than or equal to gasTipCap. - if tx.GasFeeCapIntCmp(tx.GasTipCap()) < 0 { - return ErrTipAboveFeeCap - } - // Make sure the transaction is signed properly. - from, err := types.Sender(pool.signer, tx) - if err != nil { - return ErrInvalidSender - } - // Drop non-local transactions under our own minimal accepted gas price or tip - local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network - if !local && tx.GasTipCapIntCmp(pool.gasPrice) < 0 { - return ErrUnderpriced - } - // Ensure Opera-specific hard bounds - if recommendedGasTip, minPrice := pool.chain.EffectiveMinTip(), pool.chain.MinGasPrice(); recommendedGasTip != nil && minPrice != nil { - if tx.GasTipCapIntCmp(recommendedGasTip) < 0 { - return ErrUnderpriced - } - if tx.GasFeeCapIntCmp(new(big.Int).Add(recommendedGasTip, minPrice)) < 0 { - return ErrUnderpriced - } - } - // Ensure the transaction adheres to nonce ordering - if pool.currentState.GetNonce(from) > tx.Nonce() { - return ErrNonceTooLow - } - // Transactor should have enough funds to cover the costs - // cost == V + GP * GL - if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { - return ErrInsufficientFunds - } - // Ensure the transaction has more gas than the basic tx fee. - intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil) - if err != nil { - return err - } - if tx.Gas() < intrGas { - return ErrIntrinsicGas - } - return nil -} - -// add validates a transaction and inserts it into the non-executable queue for later -// pending promotion and execution. If the transaction is a replacement for an already -// pending or queued one, it overwrites the previous transaction if its price is higher. -// -// If a newly added transaction is marked as local, its sending account will be -// be added to the allowlist, preventing any associated transaction from being dropped -// out of the pool due to pricing constraints. -func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err error) { - // If the transaction is already known, discard it - hash := tx.Hash() - if pool.all.Get(hash) != nil { - log.Trace("Discarding already known transaction", "hash", hash) - return false, ErrAlreadyKnown - } - // Make the local flag. If it's from local source or it's from the network but - // the sender is marked as local previously, treat it as the local transaction. - isLocal := local || pool.locals.containsTx(tx) - - // If the transaction fails basic validation, discard it - if err := pool.validateTx(tx, isLocal); err != nil { - log.Trace("Discarding invalid transaction", "hash", hash, "err", err) - invalidTxMeter.Mark(1) - return false, err - } - // If the transaction pool is full, discard underpriced transactions - if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue { - // If the new transaction is underpriced, don't accept it - if !isLocal && pool.priced.Underpriced(tx) { - log.Trace("Discarding underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) - underpricedTxMeter.Mark(1) - return false, ErrUnderpriced - } - // New transaction is better than our worse ones, make room for it. - // If it's a local transaction, forcibly discard all available transactions. - // Otherwise if we can't make enough room for new one, abort the operation. - drop, success := pool.priced.Discard(pool.all.Slots()-int(pool.config.GlobalSlots+pool.config.GlobalQueue)+numSlots(tx), isLocal) - - // Special case, we still can't make the room for the new remote one. - if !isLocal && !success { - log.Trace("Discarding overflown transaction", "hash", hash) - overflowedTxMeter.Mark(1) - return false, ErrTxPoolOverflow - } - // Kick out the underpriced remote transactions. - for _, tx := range drop { - log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) - underpricedTxMeter.Mark(1) - pool.removeTx(tx.Hash(), false) - } - } - // Try to replace an existing transaction in the pending pool - from, _ := types.Sender(pool.signer, tx) // already validated - if list := pool.pending[from]; list != nil && list.Overlaps(tx) { - // Nonce already pending, check if required price bump is met - inserted, old := list.Add(tx, pool.config.PriceBump) - if !inserted { - pendingDiscardMeter.Mark(1) - return false, ErrReplaceUnderpriced - } - // New transaction is better, replace old one - if old != nil { - pool.all.Remove(old.Hash()) - pool.priced.Removed(1) - pendingReplaceMeter.Mark(1) - } - pool.all.Add(tx, isLocal) - pool.priced.Put(tx, isLocal) - pool.journalTx(from, tx) - pool.queueTxEvent(tx) - log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To()) - - // Successful promotion, bump the heartbeat - pool.beats[from] = time.Now() - return old != nil, nil - } - // New transaction isn't replacing a pending one, push into queue - replaced, err = pool.enqueueTx(hash, tx, isLocal, true) - if err != nil { - return false, err - } - // Mark local addresses and journal local transactions - if local && !pool.locals.contains(from) { - log.Info("Setting new local account", "address", from) - pool.locals.add(from) - pool.priced.Removed(pool.all.RemoteToLocals(pool.locals)) // Migrate the remotes if it's marked as local first time. - } - if isLocal { - localGauge.Inc(1) - } - pool.journalTx(from, tx) - - log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To()) - return replaced, nil -} - -// enqueueTx inserts a new transaction into the non-executable transaction queue. -// -// Note, this method assumes the pool lock is held! -func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction, local bool, addAll bool) (bool, error) { - // Try to insert the transaction into the future queue - from, _ := types.Sender(pool.signer, tx) // already validated - if pool.queue[from] == nil { - pool.queue[from] = newTxList(false) - } - inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump) - if !inserted { - // An older transaction was better, discard this - queuedDiscardMeter.Mark(1) - return false, ErrReplaceUnderpriced - } - // Discard any previous transaction and mark this - if old != nil { - pool.all.Remove(old.Hash()) - pool.priced.Removed(1) - queuedReplaceMeter.Mark(1) - } else { - // Nothing was replaced, bump the queued counter - queuedGauge.Inc(1) - } - // If the transaction isn't in lookup set but it's expected to be there, - // show the error log. - if pool.all.Get(hash) == nil && !addAll { - log.Error("Missing transaction in lookup set, please report the issue", "hash", hash) - } - if addAll { - pool.all.Add(tx, local) - pool.priced.Put(tx, local) - } - // If we never record the heartbeat, do it right now. - if _, exist := pool.beats[from]; !exist { - pool.beats[from] = time.Now() - } - return old != nil, nil -} - -// journalTx adds the specified transaction to the local disk journal if it is -// deemed to have been sent from a local account. -func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) { - // Only journal if it's enabled and the transaction is local - if pool.journal == nil || !pool.locals.contains(from) { - return - } - if err := pool.journal.insert(tx); err != nil { - log.Warn("Failed to journal local transaction", "err", err) - } -} - -// promoteTx adds a transaction to the pending (processable) list of transactions -// and returns whether it was inserted or an older was better. -// -// Note, this method assumes the pool lock is held! -func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) bool { - // Try to insert the transaction into the pending queue - if pool.pending[addr] == nil { - pool.pending[addr] = newTxList(true) - } - list := pool.pending[addr] - - inserted, old := list.Add(tx, pool.config.PriceBump) - if !inserted { - // An older transaction was better, discard this - pool.all.Remove(hash) - pool.priced.Removed(1) - pendingDiscardMeter.Mark(1) - return false - } - // Otherwise discard any previous transaction and mark this - if old != nil { - pool.all.Remove(old.Hash()) - pool.priced.Removed(1) - pendingReplaceMeter.Mark(1) - } else { - // Nothing was replaced, bump the pending counter - pendingGauge.Inc(1) - } - // Set the potentially new pending nonce and notify any subsystems of the new tx - pool.pendingNonces.set(addr, tx.Nonce()+1) - - // Successful promotion, bump the heartbeat - pool.beats[addr] = time.Now() - return true -} - -// AddLocals enqueues a batch of transactions into the pool if they are valid, marking the -// senders as a local ones, ensuring they go around the local pricing constraints. -// -// This method is used to add transactions from the RPC API and performs synchronous pool -// reorganization and event propagation. -func (pool *TxPool) AddLocals(txs []*types.Transaction) []error { - return pool.addTxs(txs, !pool.config.NoLocals, true) -} - -// AddLocal enqueues a single local transaction into the pool if it is valid. This is -// a convenience wrapper aroundd AddLocals. -func (pool *TxPool) AddLocal(tx *types.Transaction) error { - errs := pool.AddLocals([]*types.Transaction{tx}) - return errs[0] -} - -// AddRemotes enqueues a batch of transactions into the pool if they are valid. If the -// senders are not among the locally tracked ones, full pricing constraints will apply. -// -// This method is used to add transactions from the p2p network and does not wait for pool -// reorganization and internal event propagation. -func (pool *TxPool) AddRemotes(txs []*types.Transaction) []error { - return pool.addTxs(txs, false, false) -} - -// This is like AddRemotes, but waits for pool reorganization. Tests use this method. -func (pool *TxPool) AddRemotesSync(txs []*types.Transaction) []error { - return pool.addTxs(txs, false, true) -} - -// This is like AddRemotes with a single transaction, but waits for pool reorganization. Tests use this method. -func (pool *TxPool) addRemoteSync(tx *types.Transaction) error { - errs := pool.AddRemotesSync([]*types.Transaction{tx}) - return errs[0] -} - -// AddRemote enqueues a single transaction into the pool if it is valid. This is a convenience -// wrapper around AddRemotes. -// -// Deprecated: use AddRemotes -func (pool *TxPool) AddRemote(tx *types.Transaction) error { - errs := pool.AddRemotes([]*types.Transaction{tx}) - return errs[0] -} - -// addTxs attempts to queue a batch of transactions if they are valid. -func (pool *TxPool) addTxs(txs []*types.Transaction, local, sync bool) []error { - arrivedAt := time.Now() - // Filter out known ones without obtaining the pool lock or recovering signatures - var ( - errs = make([]error, len(txs)) - news = make([]*types.Transaction, 0, len(txs)) - ) - for i, tx := range txs { - // If the transaction is known, pre-set the error slot - if pool.all.Get(tx.Hash()) != nil { - errs[i] = ErrAlreadyKnown - continue - } - // Exclude transactions with invalid signatures as soon as - // possible and cache senders in transactions before - // obtaining lock - _, err := types.Sender(pool.signer, tx) - if err != nil { - errs[i] = ErrInvalidSender - invalidTxMeter.Mark(1) - continue - } - // Accumulate all unknown transactions for deeper processing - news = append(news, tx) - } - if len(news) == 0 { - return errs - } - - // Process all the new transaction and merge any errors into the original slice - pool.mu.Lock() - newErrs, dirtyAddrs := pool.addTxsLocked(news, local) - pool.mu.Unlock() - - // memorize tx time of validated transactions - for i, tx := range news { - if newErrs[i] == nil { - txtime.Validated(tx.Hash(), arrivedAt) - } - } - - var nilSlot = 0 - for _, err := range newErrs { - for errs[nilSlot] != nil { - nilSlot++ - } - errs[nilSlot] = err - nilSlot++ - } - // Reorg the pool internals if needed and return - done := pool.requestPromoteExecutables(dirtyAddrs) - if sync { - <-done - } - return errs -} - -// addTxsLocked attempts to queue a batch of transactions if they are valid. -// The transaction pool lock must be held. -func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) ([]error, *accountSet) { - dirty := newAccountSet(pool.signer) - errs := make([]error, len(txs)) - for i, tx := range txs { - replaced, err := pool.add(tx, local) - errs[i] = err - if err == nil && !replaced { - dirty.addTx(tx) - } - } - validTxMeter.Mark(int64(len(dirty.accounts))) - return errs, dirty -} - -// Status returns the status (unknown/pending/queued) of a batch of transactions -// identified by their hashes. -func (pool *TxPool) Status(hashes []common.Hash) []TxStatus { - status := make([]TxStatus, len(hashes)) - for i, hash := range hashes { - tx := pool.Get(hash) - if tx == nil { - continue - } - from, _ := types.Sender(pool.signer, tx) // already validated - pool.mu.RLock() - if txList := pool.pending[from]; txList != nil && txList.txs.items[tx.Nonce()] != nil { - status[i] = TxStatusPending - } else if txList := pool.queue[from]; txList != nil && txList.txs.items[tx.Nonce()] != nil { - status[i] = TxStatusQueued - } - // implicit else: the tx may have been included into a block between - // checking pool.Get and obtaining the lock. In that case, TxStatusUnknown is correct - pool.mu.RUnlock() - } - return status -} - -// Get returns a transaction if it is contained in the pool and nil otherwise. -func (pool *TxPool) Get(hash common.Hash) *types.Transaction { - return pool.all.Get(hash) -} - -// Has returns an indicator whether txpool has a transaction cached with the -// given hash. -func (pool *TxPool) Has(hash common.Hash) bool { - return pool.all.Get(hash) != nil -} - -func (pool *TxPool) OnlyNotExisting(hashes []common.Hash) []common.Hash { - return pool.all.OnlyNotExisting(hashes) -} - -// removeTx removes a single transaction from the queue, moving all subsequent -// transactions back to the future queue. -func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) { - // Fetch the transaction we wish to delete - tx := pool.all.Get(hash) - if tx == nil { - return - } - addr, _ := types.Sender(pool.signer, tx) // already validated during insertion - - // Remove it from the list of known transactions - pool.all.Remove(hash) - if outofbound { - pool.priced.Removed(1) - } - if pool.locals.contains(addr) { - localGauge.Dec(1) - } - // Remove the transaction from the pending lists and reset the account nonce - if pending := pool.pending[addr]; pending != nil { - if removed, invalids := pending.Remove(tx); removed { - // If no more pending transactions are left, remove the list - if pending.Empty() { - delete(pool.pending, addr) - } - // Postpone any invalidated transactions - for _, tx := range invalids { - // Internal shuffle shouldn't touch the lookup set. - pool.enqueueTx(tx.Hash(), tx, false, false) - } - // Update the account nonce if needed - pool.pendingNonces.setIfLower(addr, tx.Nonce()) - // Reduce the pending counter - pendingGauge.Dec(int64(1 + len(invalids))) - return - } - } - // Transaction is in the future queue - if future := pool.queue[addr]; future != nil { - if removed, _ := future.Remove(tx); removed { - // Reduce the queued counter - queuedGauge.Dec(1) - } - if future.Empty() { - delete(pool.queue, addr) - delete(pool.beats, addr) - } - } -} - -// requestReset requests a pool reset to the new head block. -// The returned channel is closed when the reset has occurred. -func (pool *TxPool) requestReset(oldHead *EvmHeader, newHead *EvmHeader) chan struct{} { - select { - case pool.reqResetCh <- &txpoolResetRequest{oldHead, newHead}: - return <-pool.reorgDoneCh - case <-pool.reorgShutdownCh: - return pool.reorgShutdownCh - } -} - -// requestPromoteExecutables requests transaction promotion checks for the given addresses. -// The returned channel is closed when the promotion checks have occurred. -func (pool *TxPool) requestPromoteExecutables(set *accountSet) chan struct{} { - select { - case pool.reqPromoteCh <- set: - return <-pool.reorgDoneCh - case <-pool.reorgShutdownCh: - return pool.reorgShutdownCh - } -} - -// queueTxEvent enqueues a transaction event to be sent in the next reorg run. -func (pool *TxPool) queueTxEvent(tx *types.Transaction) { - select { - case pool.queueTxEventCh <- tx: - case <-pool.reorgShutdownCh: - } -} - -// scheduleReorgLoop schedules runs of reset and promoteExecutables. Code above should not -// call those methods directly, but request them being run using requestReset and -// requestPromoteExecutables instead. -func (pool *TxPool) scheduleReorgLoop() { - defer pool.wg.Done() - - var ( - curDone chan struct{} // non-nil while runReorg is active - nextDone = make(chan struct{}) - launchNextRun bool - reset *txpoolResetRequest - dirtyAccounts *accountSet - queuedEvents = make(map[common.Address]*txSortedMap) - ) - for { - // Launch next background reorg if needed - if curDone == nil && launchNextRun { - // Run the background reorg and announcements - go pool.runReorg(nextDone, reset, dirtyAccounts, queuedEvents) - - // Prepare everything for the next round of reorg - curDone, nextDone = nextDone, make(chan struct{}) - launchNextRun = false - - reset, dirtyAccounts = nil, nil - queuedEvents = make(map[common.Address]*txSortedMap) - } - - select { - case req := <-pool.reqResetCh: - // Reset request: update head if request is already pending. - if reset == nil { - reset = req - } else { - reset.newHead = req.newHead - } - launchNextRun = true - pool.reorgDoneCh <- nextDone - - case req := <-pool.reqPromoteCh: - // Promote request: update address set if request is already pending. - if dirtyAccounts == nil { - dirtyAccounts = req - } else { - dirtyAccounts.merge(req) - } - launchNextRun = true - pool.reorgDoneCh <- nextDone - - case tx := <-pool.queueTxEventCh: - // Queue up the event, but don't schedule a reorg. It's up to the caller to - // request one later if they want the events sent. - addr, _ := types.Sender(pool.signer, tx) - if _, ok := queuedEvents[addr]; !ok { - queuedEvents[addr] = newTxSortedMap() - } - queuedEvents[addr].Put(tx) - - case <-curDone: - curDone = nil - - case <-pool.reorgShutdownCh: - // Wait for current run to finish. - if curDone != nil { - <-curDone - } - close(nextDone) - return - } - } -} - -// runReorg runs reset and promoteExecutables on behalf of scheduleReorgLoop. -func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirtyAccounts *accountSet, events map[common.Address]*txSortedMap) { - defer close(done) - - var promoteAddrs []common.Address - if dirtyAccounts != nil && reset == nil { - // Only dirty accounts need to be promoted, unless we're resetting. - // For resets, all addresses in the tx queue will be promoted and - // the flatten operation can be avoided. - promoteAddrs = dirtyAccounts.flatten() - } - pool.mu.Lock() - if reset != nil { - // Reset from the old head to the new, rescheduling any reorged transactions - pool.reset(reset.oldHead, reset.newHead) - - // Nonces were reset, discard any events that became stale - for addr := range events { - events[addr].Forward(pool.pendingNonces.get(addr)) - if events[addr].Len() == 0 { - delete(events, addr) - } - } - // Reset needs promote for all addresses - promoteAddrs = make([]common.Address, 0, len(pool.queue)) - for addr := range pool.queue { - promoteAddrs = append(promoteAddrs, addr) - } - } - // Check for pending transactions for every account that sent new ones - promoted := pool.promoteExecutables(promoteAddrs) - - // If a new block appeared, validate the pool of pending transactions. This will - // remove any transaction that has been included in the block or was invalidated - // because of another transaction (e.g. higher gas price). - if reset != nil { - pool.demoteUnexecutables() - if pool.chain.MinGasPrice() != nil { - // Opera-specific base fee - pool.priced.SetBaseFee(pool.chain.MinGasPrice()) - } else { - // for tests only - if reset.newHead != nil && pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) { - pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead.EthHeader()) - pool.priced.SetBaseFee(pendingBaseFee) - } - } - } - // Ensure pool.queue and pool.pending sizes stay within the configured limits. - pool.truncatePending() - pool.truncateQueue() - - // Update all accounts to the latest known pending nonce - for addr, list := range pool.pending { - highestPending := list.LastElement() - pool.pendingNonces.set(addr, highestPending.Nonce()+1) - } - pool.mu.Unlock() - - // Notify subsystems for newly added transactions - for _, tx := range promoted { - addr, _ := types.Sender(pool.signer, tx) - if _, ok := events[addr]; !ok { - events[addr] = newTxSortedMap() - } - events[addr].Put(tx) - } - if len(events) > 0 { - var txs []*types.Transaction - for _, set := range events { - txs = append(txs, set.Flatten()...) - } - pool.txFeed.Send(NewTxsNotify{txs}) - } -} - -// reset retrieves the current state of the blockchain and ensures the content -// of the transaction pool is valid with regard to the chain state. -func (pool *TxPool) reset(oldHead, newHead *EvmHeader) { - // update chain config (Opera-specific) - if newConfig := pool.chain.Config(); newConfig != nil { - pool.chainconfig = newConfig - } - - // If we're reorging an old state, reinject all dropped transactions - var reinject types.Transactions - - if oldHead != nil && oldHead.Hash != newHead.ParentHash { - // If the reorg is too deep, avoid doing it (will happen during fast sync) - oldNum := oldHead.Number.Uint64() - newNum := newHead.Number.Uint64() - - if depth := uint64(math.Abs(float64(oldNum) - float64(newNum))); depth > 64 { - log.Debug("Skipping deep transaction reorg", "depth", depth) - } else { - // Reorg seems shallow enough to pull in all transactions into memory - var discarded, included types.Transactions - var ( - rem = pool.chain.GetBlock(oldHead.Hash, oldHead.Number.Uint64()) - add = pool.chain.GetBlock(newHead.Hash, newHead.Number.Uint64()) - ) - if rem == nil { - // This can happen if a setHead is performed, where we simply discard the old - // head from the chain. - // If that is the case, we don't have the lost transactions any more, and - // there's nothing to add - if newNum >= oldNum { - // If we reorged to a same or higher number, then it's not a case of setHead - log.Warn("Transaction pool reset with missing oldhead", - "old", oldHead.Hash, "oldnum", oldNum, "new", newHead.Hash, "newnum", newNum) - return - } - // If the reorg ended up on a lower number, it's indicative of setHead being the cause - log.Debug("Skipping transaction reset caused by setHead", - "old", oldHead.Hash, "oldnum", oldNum, "new", newHead.Hash, "newnum", newNum) - // We still need to update the current state s.th. the lost transactions can be readded by the user - } else { - for rem.NumberU64() > add.NumberU64() { - discarded = append(discarded, rem.Transactions...) - if rem = pool.chain.GetBlock(rem.ParentHash, rem.NumberU64()-1); rem == nil { - log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash) - return - } - } - for add.NumberU64() > rem.NumberU64() { - included = append(included, add.Transactions...) - if add = pool.chain.GetBlock(add.ParentHash, add.NumberU64()-1); add == nil { - log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash) - return - } - } - for rem.Hash != add.Hash { - discarded = append(discarded, rem.Transactions...) - if rem = pool.chain.GetBlock(rem.ParentHash, rem.NumberU64()-1); rem == nil { - log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash) - return - } - included = append(included, add.Transactions...) - if add = pool.chain.GetBlock(add.ParentHash, add.NumberU64()-1); add == nil { - log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash) - return - } - } - reinject = types.TxDifference(discarded, included) - } - } - } - // Initialize the internal state to the current head - if newHead == nil { - newHead = pool.chain.CurrentBlock().Header() // Special case during testing - } - statedb, err := pool.chain.StateAt(newHead.Root) - if err != nil && pool.currentState == nil { - log.Debug("Failed to access EVM state", "block", newHead.Number, "root", newHead.Root, "err", err) - statedb, err = pool.chain.StateAt(common.Hash{}) - } - if err != nil { - log.Error("Failed to reset txpool state", "block", newHead.Number, "root", newHead.Root, "err", err) - return - } - pool.currentState = statedb - pool.pendingNonces = newTxNoncer(statedb) - pool.currentMaxGas = pool.chain.MaxGasLimit() - - // Inject any transactions discarded due to reorgs - log.Debug("Reinjecting stale transactions", "count", len(reinject)) - senderCacher.recover(pool.signer, reinject) - pool.addTxsLocked(reinject, false) - - // Update all fork indicator by next pending block number. - next := new(big.Int).Add(newHead.Number, big.NewInt(1)) - pool.istanbul = pool.chainconfig.IsIstanbul(next) - pool.eip2718 = pool.chainconfig.IsBerlin(next) - pool.eip1559 = pool.chainconfig.IsLondon(next) -} - -// promoteExecutables moves transactions that have become processable from the -// future queue to the set of pending transactions. During this process, all -// invalidated transactions (low nonce, low balance) are deleted. -func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Transaction { - // Track the promoted transactions to broadcast them at once - var promoted []*types.Transaction - - // Iterate over all accounts and promote any executable transactions - for _, addr := range accounts { - list := pool.queue[addr] - if list == nil { - continue // Just in case someone calls with a non existing account - } - // Drop all transactions that are deemed too old (low nonce) - forwards := list.Forward(pool.currentState.GetNonce(addr)) - for _, tx := range forwards { - hash := tx.Hash() - pool.all.Remove(hash) - } - log.Trace("Removed old queued transactions", "count", len(forwards)) - // Drop all transactions that are too costly (low balance or out of gas) - drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) - for _, tx := range drops { - hash := tx.Hash() - pool.all.Remove(hash) - } - log.Trace("Removed unpayable queued transactions", "count", len(drops)) - queuedNofundsMeter.Mark(int64(len(drops))) - - // Gather all executable transactions and promote them - readies := list.Ready(pool.pendingNonces.get(addr)) - for _, tx := range readies { - hash := tx.Hash() - if pool.promoteTx(addr, hash, tx) { - promoted = append(promoted, tx) - } - } - log.Trace("Promoted queued transactions", "count", len(promoted)) - queuedGauge.Dec(int64(len(readies))) - - // Drop all transactions over the allowed limit - var caps types.Transactions - if !pool.locals.contains(addr) { - caps = list.Cap(int(pool.config.AccountQueue)) - for _, tx := range caps { - hash := tx.Hash() - pool.all.Remove(hash) - log.Trace("Removed cap-exceeding queued transaction", "hash", hash) - } - queuedRateLimitMeter.Mark(int64(len(caps))) - } - // Mark all the items dropped as removed - pool.priced.Removed(len(forwards) + len(drops) + len(caps)) - queuedGauge.Dec(int64(len(forwards) + len(drops) + len(caps))) - if pool.locals.contains(addr) { - localGauge.Dec(int64(len(forwards) + len(drops) + len(caps))) - } - // Delete the entire queue entry if it became empty. - if list.Empty() { - delete(pool.queue, addr) - delete(pool.beats, addr) - } - } - return promoted -} - -// truncatePending removes transactions from the pending queue if the pool is above the -// pending limit. The algorithm tries to reduce transaction counts by an approximately -// equal number for all for accounts with many pending transactions. -func (pool *TxPool) truncatePending() { - pending := uint64(0) - for _, list := range pool.pending { - pending += uint64(list.Len()) - } - if pending <= pool.config.GlobalSlots { - return - } - - pendingBeforeCap := pending - // Assemble a spam order to penalize large transactors first - spammers := prque.New(nil) - for addr, list := range pool.pending { - // Only evict transactions from high rollers - if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots { - spammers.Push(addr, int64(list.Len())) - } - } - // Gradually drop transactions from offenders - offenders := []common.Address{} - for pending > pool.config.GlobalSlots && !spammers.Empty() { - // Retrieve the next offender if not local address - offender, _ := spammers.Pop() - offenders = append(offenders, offender.(common.Address)) - - // Equalize balances until all the same or below threshold - if len(offenders) > 1 { - // Calculate the equalization threshold for all current offenders - threshold := pool.pending[offender.(common.Address)].Len() - - // Iteratively reduce all offenders until below limit or threshold reached - for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold { - for i := 0; i < len(offenders)-1; i++ { - list := pool.pending[offenders[i]] - - caps := list.Cap(list.Len() - 1) - for _, tx := range caps { - // Drop the transaction from the global pools too - hash := tx.Hash() - pool.all.Remove(hash) - - // Update the account nonce to the dropped transaction - pool.pendingNonces.setIfLower(offenders[i], tx.Nonce()) - log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) - } - pool.priced.Removed(len(caps)) - pendingGauge.Dec(int64(len(caps))) - if pool.locals.contains(offenders[i]) { - localGauge.Dec(int64(len(caps))) - } - pending-- - } - } - } - } - - // If still above threshold, reduce to limit or min allowance - if pending > pool.config.GlobalSlots && len(offenders) > 0 { - for pending > pool.config.GlobalSlots && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.AccountSlots { - for _, addr := range offenders { - list := pool.pending[addr] - - caps := list.Cap(list.Len() - 1) - for _, tx := range caps { - // Drop the transaction from the global pools too - hash := tx.Hash() - pool.all.Remove(hash) - - // Update the account nonce to the dropped transaction - pool.pendingNonces.setIfLower(addr, tx.Nonce()) - log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) - } - pool.priced.Removed(len(caps)) - pendingGauge.Dec(int64(len(caps))) - if pool.locals.contains(addr) { - localGauge.Dec(int64(len(caps))) - } - pending-- - } - } - } - pendingRateLimitMeter.Mark(int64(pendingBeforeCap - pending)) -} - -// truncateQueue drops the oldes transactions in the queue if the pool is above the global queue limit. -func (pool *TxPool) truncateQueue() { - queued := uint64(0) - for _, list := range pool.queue { - queued += uint64(list.Len()) - } - if queued <= pool.config.GlobalQueue { - return - } - - // Sort all accounts with queued transactions by heartbeat - addresses := make(addressesByHeartbeat, 0, len(pool.queue)) - for addr := range pool.queue { - if !pool.locals.contains(addr) { // don't drop locals - addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]}) - } - } - sort.Sort(addresses) - - // Drop transactions until the total is below the limit or only locals remain - for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; { - addr := addresses[len(addresses)-1] - list := pool.queue[addr.address] - - addresses = addresses[:len(addresses)-1] - - // Drop all transactions if they are less than the overflow - if size := uint64(list.Len()); size <= drop { - for _, tx := range list.Flatten() { - pool.removeTx(tx.Hash(), true) - } - drop -= size - queuedRateLimitMeter.Mark(int64(size)) - continue - } - // Otherwise drop only last few transactions - txs := list.Flatten() - for i := len(txs) - 1; i >= 0 && drop > 0; i-- { - pool.removeTx(txs[i].Hash(), true) - drop-- - queuedRateLimitMeter.Mark(1) - } - } -} - -// demoteUnexecutables removes invalid and processed transactions from the pools -// executable/pending queue and any subsequent transactions that become unexecutable -// are moved back into the future queue. -// -// Note: transactions are not marked as removed in the priced list because re-heaping -// is always explicitly triggered by SetBaseFee and it would be unnecessary and wasteful -// to trigger a re-heap is this function -func (pool *TxPool) demoteUnexecutables() { - // Iterate over all accounts and demote any non-executable transactions - for addr, list := range pool.pending { - nonce := pool.currentState.GetNonce(addr) - - // Drop all transactions that are deemed too old (low nonce) - olds := list.Forward(nonce) - for _, tx := range olds { - hash := tx.Hash() - pool.all.Remove(hash) - log.Trace("Removed old pending transaction", "hash", hash) - } - // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later - drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) - for _, tx := range drops { - hash := tx.Hash() - log.Trace("Removed unpayable pending transaction", "hash", hash) - pool.all.Remove(hash) - } - pendingNofundsMeter.Mark(int64(len(drops))) - - for _, tx := range invalids { - hash := tx.Hash() - log.Trace("Demoting pending transaction", "hash", hash) - - // Internal shuffle shouldn't touch the lookup set. - pool.enqueueTx(hash, tx, false, false) - } - pendingGauge.Dec(int64(len(olds) + len(drops) + len(invalids))) - if pool.locals.contains(addr) { - localGauge.Dec(int64(len(olds) + len(drops) + len(invalids))) - } - // If there's a gap in front, alert (should never happen) and postpone all transactions - if list.Len() > 0 && list.txs.Get(nonce) == nil { - gapped := list.Cap(0) - for _, tx := range gapped { - hash := tx.Hash() - log.Error("Demoting invalidated transaction", "hash", hash) - - // Internal shuffle shouldn't touch the lookup set. - pool.enqueueTx(hash, tx, false, false) - } - pendingGauge.Dec(int64(len(gapped))) - } - // Delete the entire pending entry if it became empty. - if list.Empty() { - delete(pool.pending, addr) - } - } -} - -// addressByHeartbeat is an account address tagged with its last activity timestamp. -type addressByHeartbeat struct { - address common.Address - heartbeat time.Time -} - -type addressesByHeartbeat []addressByHeartbeat - -func (a addressesByHeartbeat) Len() int { return len(a) } -func (a addressesByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } -func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -// accountSet is simply a set of addresses to check for existence, and a signer -// capable of deriving addresses from transactions. -type accountSet struct { - accounts map[common.Address]struct{} - signer types.Signer - cache *[]common.Address -} - -// newAccountSet creates a new address set with an associated signer for sender -// derivations. -func newAccountSet(signer types.Signer, addrs ...common.Address) *accountSet { - as := &accountSet{ - accounts: make(map[common.Address]struct{}), - signer: signer, - } - for _, addr := range addrs { - as.add(addr) - } - return as -} - -// contains checks if a given address is contained within the set. -func (as *accountSet) contains(addr common.Address) bool { - _, exist := as.accounts[addr] - return exist -} - -func (as *accountSet) empty() bool { - return len(as.accounts) == 0 -} - -// containsTx checks if the sender of a given tx is within the set. If the sender -// cannot be derived, this method returns false. -func (as *accountSet) containsTx(tx *types.Transaction) bool { - if addr, err := types.Sender(as.signer, tx); err == nil { - return as.contains(addr) - } - return false -} - -// add inserts a new address into the set to track. -func (as *accountSet) add(addr common.Address) { - as.accounts[addr] = struct{}{} - as.cache = nil -} - -// addTx adds the sender of tx into the set. -func (as *accountSet) addTx(tx *types.Transaction) { - if addr, err := types.Sender(as.signer, tx); err == nil { - as.add(addr) - } -} - -// flatten returns the list of addresses within this set, also caching it for later -// reuse. The returned slice should not be changed! -func (as *accountSet) flatten() []common.Address { - if as.cache == nil { - accounts := make([]common.Address, 0, len(as.accounts)) - for account := range as.accounts { - accounts = append(accounts, account) - } - as.cache = &accounts - } - return *as.cache -} - -// merge adds all addresses from the 'other' set into 'as'. -func (as *accountSet) merge(other *accountSet) { - for addr := range other.accounts { - as.accounts[addr] = struct{}{} - } - as.cache = nil -} - -// txLookup is used internally by TxPool to track transactions while allowing -// lookup without mutex contention. -// -// Note, although this type is properly protected against concurrent access, it -// is **not** a type that should ever be mutated or even exposed outside of the -// transaction pool, since its internal state is tightly coupled with the pools -// internal mechanisms. The sole purpose of the type is to permit out-of-bound -// peeking into the pool in TxPool.Get without having to acquire the widely scoped -// TxPool.mu mutex. -// -// This lookup set combines the notion of "local transactions", which is useful -// to build upper-level structure. -type txLookup struct { - slots int - lock sync.RWMutex - locals map[common.Hash]*types.Transaction - remotes map[common.Hash]*types.Transaction -} - -// newTxLookup returns a new txLookup structure. -func newTxLookup() *txLookup { - return &txLookup{ - locals: make(map[common.Hash]*types.Transaction), - remotes: make(map[common.Hash]*types.Transaction), - } -} - -func (t *txLookup) SampleHashes(max int) []common.Hash { - t.lock.RLock() - defer t.lock.RUnlock() - res := make([]common.Hash, 0, max) - skip := 0 - if len(t.locals)+len(t.remotes) > max { - skip = rand.Intn(len(t.locals) + len(t.remotes) - max) - } - forEach := func(key common.Hash) bool { - if len(res) >= max { - return false - } - if skip > 0 { - skip-- - return true - } - res = append(res, key) - return true - } - for key := range t.locals { - if !forEach(key) { - break - } - } - for key := range t.remotes { - if !forEach(key) { - break - } - } - return res -} - -// Range calls f on each key and value present in the map. The callback passed -// should return the indicator whether the iteration needs to be continued. -// Callers need to specify which set (or both) to be iterated. -func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction, local bool) bool, local bool, remote bool) { - t.lock.RLock() - defer t.lock.RUnlock() - - if local { - for key, value := range t.locals { - if !f(key, value, true) { - return - } - } - } - if remote { - for key, value := range t.remotes { - if !f(key, value, false) { - return - } - } - } -} - -// Get returns a transaction if it exists in the lookup, or nil if not found. -func (t *txLookup) Get(hash common.Hash) *types.Transaction { - t.lock.RLock() - defer t.lock.RUnlock() - - if tx := t.locals[hash]; tx != nil { - return tx - } - return t.remotes[hash] -} - -func (t *txLookup) OnlyNotExisting(hashes []common.Hash) []common.Hash { - t.lock.RLock() - defer t.lock.RUnlock() - notExisting := make([]common.Hash, 0, len(hashes)) - for _, txid := range hashes { - if t.locals[txid] == nil && t.remotes[txid] == nil { - notExisting = append(notExisting, txid) - } - } - return notExisting -} - -// GetLocal returns a transaction if it exists in the lookup, or nil if not found. -func (t *txLookup) GetLocal(hash common.Hash) *types.Transaction { - t.lock.RLock() - defer t.lock.RUnlock() - - return t.locals[hash] -} - -// GetRemote returns a transaction if it exists in the lookup, or nil if not found. -func (t *txLookup) GetRemote(hash common.Hash) *types.Transaction { - t.lock.RLock() - defer t.lock.RUnlock() - - return t.remotes[hash] -} - -// Count returns the current number of transactions in the lookup. -func (t *txLookup) Count() int { - t.lock.RLock() - defer t.lock.RUnlock() - - return len(t.locals) + len(t.remotes) -} - -// LocalCount returns the current number of local transactions in the lookup. -func (t *txLookup) LocalCount() int { - t.lock.RLock() - defer t.lock.RUnlock() - - return len(t.locals) -} - -// RemoteCount returns the current number of remote transactions in the lookup. -func (t *txLookup) RemoteCount() int { - t.lock.RLock() - defer t.lock.RUnlock() - - return len(t.remotes) -} - -// Slots returns the current number of slots used in the lookup. -func (t *txLookup) Slots() int { - t.lock.RLock() - defer t.lock.RUnlock() - - return t.slots -} - -// Add adds a transaction to the lookup. -func (t *txLookup) Add(tx *types.Transaction, local bool) { - t.lock.Lock() - defer t.lock.Unlock() - - t.slots += numSlots(tx) - slotsGauge.Update(int64(t.slots)) - - if local { - t.locals[tx.Hash()] = tx - } else { - t.remotes[tx.Hash()] = tx - } -} - -// Remove removes a transaction from the lookup. -func (t *txLookup) Remove(hash common.Hash) { - t.lock.Lock() - defer t.lock.Unlock() - - tx, ok := t.locals[hash] - if !ok { - tx, ok = t.remotes[hash] - } - if !ok { - log.Error("No transaction found to be deleted", "hash", hash) - return - } - t.slots -= numSlots(tx) - slotsGauge.Update(int64(t.slots)) - - delete(t.locals, hash) - delete(t.remotes, hash) -} - -// RemoteToLocals migrates the transactions belongs to the given locals to locals -// set. The assumption is held the locals set is thread-safe to be used. -func (t *txLookup) RemoteToLocals(locals *accountSet) int { - t.lock.Lock() - defer t.lock.Unlock() - - var migrated int - for hash, tx := range t.remotes { - if locals.containsTx(tx) { - t.locals[hash] = tx - delete(t.remotes, hash) - migrated += 1 - } - } - return migrated -} - -// RemotesBelowTip finds all remote transactions below the given gas price threshold. -func (t *txLookup) RemotesBelowTip(threshold *big.Int) types.Transactions { - found := make(types.Transactions, 0, 128) - t.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool { - if tx.GasTipCapIntCmp(threshold) < 0 { - found = append(found, tx) - } - return true - }, false, true) // Only iterate remotes - return found -} - -// numSlots calculates the number of slots needed for a single transaction. -func numSlots(tx *types.Transaction) int { - return int((tx.Size() + txSlotSize - 1) / txSlotSize) -} diff --git a/evm/go-x1/evmcore/tx_pool_test.go b/evm/go-x1/evmcore/tx_pool_test.go deleted file mode 100644 index 11532fe..0000000 --- a/evm/go-x1/evmcore/tx_pool_test.go +++ /dev/null @@ -1,2567 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "crypto/ecdsa" - "errors" - "fmt" - "io/ioutil" - "math/big" - "math/rand" - "os" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/params" -) - -var ( - // testTxPoolConfig is a transaction pool configuration without stateful disk - // sideeffects used during testing. - testTxPoolConfig TxPoolConfig - - // eip1559Config is a chain config with EIP-1559 enabled at block 0. - eip1559Config *params.ChainConfig -) - -func init() { - testTxPoolConfig = DefaultTxPoolConfig - testTxPoolConfig.Journal = "" - - cpy := *params.TestChainConfig - eip1559Config = &cpy - eip1559Config.BerlinBlock = common.Big0 - eip1559Config.LondonBlock = common.Big0 -} - -type testBlockChain struct { - statedb *state.StateDB - gasLimit uint64 - chainHeadFeed *event.Feed -} - -func (bc *testBlockChain) CurrentBlock() *EvmBlock { - return &EvmBlock{ - EvmHeader: EvmHeader{ - Number: big.NewInt(1), - Hash: common.Hash{}, - ParentHash: common.Hash{}, - Root: common.Hash{}, - TxHash: common.Hash{}, - Time: 0, - Coinbase: common.Address{}, - GasLimit: bc.gasLimit, - GasUsed: 0, - BaseFee: nil, - }, - Transactions: nil, - } -} - -func (bc *testBlockChain) MinGasPrice() *big.Int { - return common.Big0 -} -func (bc *testBlockChain) EffectiveMinTip() *big.Int { - return nil -} -func (bc *testBlockChain) MaxGasLimit() uint64 { - return bc.CurrentBlock().GasLimit -} -func (bc *testBlockChain) Config() *params.ChainConfig { - return nil -} - -func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *EvmBlock { - return bc.CurrentBlock() -} - -func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { - return bc.statedb, nil -} - -func (bc *testBlockChain) SubscribeNewBlock(ch chan<- ChainHeadNotify) event.Subscription { - return bc.chainHeadFeed.Subscribe(ch) -} - -func transaction(nonce uint64, gaslimit uint64, key *ecdsa.PrivateKey) *types.Transaction { - return pricedTransaction(nonce, gaslimit, big.NewInt(1), key) -} - -func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction { - tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil), types.HomesteadSigner{}, key) - return tx -} - -func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, bytes uint64) *types.Transaction { - data := make([]byte, bytes) - rand.Read(data) - - tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key) - return tx -} - -func dynamicFeeTx(nonce uint64, gaslimit uint64, gasFee *big.Int, tip *big.Int, key *ecdsa.PrivateKey) *types.Transaction { - tx, _ := types.SignNewTx(key, types.LatestSignerForChainID(params.TestChainConfig.ChainID), &types.DynamicFeeTx{ - ChainID: params.TestChainConfig.ChainID, - Nonce: nonce, - GasTipCap: tip, - GasFeeCap: gasFee, - Gas: gaslimit, - To: &common.Address{}, - Value: big.NewInt(100), - Data: nil, - AccessList: nil, - }) - return tx -} - -func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { - return setupTxPoolWithConfig(params.TestChainConfig) -} - -func setupTxPoolWithConfig(config *params.ChainConfig) (*TxPool, *ecdsa.PrivateKey) { - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 10000000, new(event.Feed)} - - key, _ := crypto.GenerateKey() - pool := NewTxPool(testTxPoolConfig, config, blockchain) - - return pool, key -} - -// validateTxPoolInternals checks various consistency invariants within the pool. -func validateTxPoolInternals(pool *TxPool) error { - pool.mu.RLock() - defer pool.mu.RUnlock() - - // Ensure the total transaction set is consistent with pending + queued - pending, queued := pool.stats() - if total := pool.all.Count(); total != pending+queued { - return fmt.Errorf("total transaction count %d != %d pending + %d queued", total, pending, queued) - } - pool.priced.Reheap() - priced, remote := pool.priced.urgent.Len()+pool.priced.floating.Len(), pool.all.RemoteCount() - if priced != remote { - return fmt.Errorf("total priced transaction count %d != %d", priced, remote) - } - // Ensure the next nonce to assign is the correct one - for addr, txs := range pool.pending { - // Find the last transaction - var last uint64 - for nonce := range txs.txs.items { - if last < nonce { - last = nonce - } - } - if nonce := pool.pendingNonces.get(addr); nonce != last+1 { - return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1) - } - } - return nil -} - -// validateEvents checks that the correct number of transaction addition events -// were fired on the pool's event feed. -func validateEvents(events chan NewTxsNotify, count int) error { - var received []*types.Transaction - - for len(received) < count { - select { - case ev := <-events: - received = append(received, ev.Txs...) - case <-time.After(time.Second): - return fmt.Errorf("event #%d not fired", len(received)) - } - } - if len(received) > count { - return fmt.Errorf("more than %d events fired: %v", count, received[count:]) - } - select { - case ev := <-events: - return fmt.Errorf("more than %d events fired: %v", count, ev.Txs) - - case <-time.After(50 * time.Millisecond): - // This branch should be "default", but it's a data race between goroutines, - // reading the event channel and pushing into it, so better wait a bit ensuring - // really nothing gets injected. - } - return nil -} - -func deriveSender(tx *types.Transaction) (common.Address, error) { - return types.Sender(types.HomesteadSigner{}, tx) -} - -type testChain struct { - *testBlockChain - address common.Address - trigger *bool -} - -// testChain.State() is used multiple times to reset the pending state. -// when simulate is true it will create a state that indicates -// that tx0 and tx1 are included in the chain. -func (c *testChain) State() (*state.StateDB, error) { - // delay "state change" by one. The tx pool fetches the - // state multiple times and by delaying it a bit we simulate - // a state change between those fetches. - stdb := c.statedb - if *c.trigger { - c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - // simulate that the new head block included tx0 and tx1 - c.statedb.SetNonce(c.address, 2) - c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether)) - *c.trigger = false - } - return stdb, nil -} - -// This test simulates a scenario where a new block is imported during a -// state reset and tests whether the pending state is in sync with the -// block head event that initiated the resetState(). -func TestStateChangeDuringTransactionPoolReset(t *testing.T) { - t.Parallel() - - var ( - key, _ = crypto.GenerateKey() - address = crypto.PubkeyToAddress(key.PublicKey) - statedb, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - trigger = false - ) - - // setup pool with 2 transaction in it - statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether)) - blockchain := &testChain{&testBlockChain{statedb, 1000000000, new(event.Feed)}, address, &trigger} - - tx0 := transaction(0, 100000, key) - tx1 := transaction(1, 100000, key) - - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) - defer pool.Stop() - - nonce := pool.Nonce(address) - if nonce != 0 { - t.Fatalf("Invalid nonce, want 0, got %d", nonce) - } - - pool.AddRemotesSync([]*types.Transaction{tx0, tx1}) - - nonce = pool.Nonce(address) - if nonce != 2 { - t.Fatalf("Invalid nonce, want 2, got %d", nonce) - } - - // trigger state change in the background - trigger = true - <-pool.requestReset(nil, nil) - - _, err := pool.Pending(false) - if err != nil { - t.Fatalf("Could not fetch pending transactions: %v", err) - } - nonce = pool.Nonce(address) - if nonce != 2 { - t.Fatalf("Invalid nonce, want 2, got %d", nonce) - } -} - -func testAddBalance(pool *TxPool, addr common.Address, amount *big.Int) { - pool.mu.Lock() - pool.currentState.AddBalance(addr, amount) - pool.mu.Unlock() -} - -func testSetNonce(pool *TxPool, addr common.Address, nonce uint64) { - pool.mu.Lock() - pool.currentState.SetNonce(addr, nonce) - pool.mu.Unlock() -} - -func TestInvalidTransactions(t *testing.T) { - t.Parallel() - - pool, key := setupTxPool() - defer pool.Stop() - - tx := transaction(0, 100, key) - from, _ := deriveSender(tx) - - testAddBalance(pool, from, big.NewInt(1)) - if err := pool.AddRemote(tx); !errors.Is(err, ErrInsufficientFunds) { - t.Error("expected", ErrInsufficientFunds) - } - - balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice())) - testAddBalance(pool, from, balance) - if err := pool.AddRemote(tx); !errors.Is(err, ErrIntrinsicGas) { - t.Error("expected", ErrIntrinsicGas, "got", err) - } - - testSetNonce(pool, from, 1) - testAddBalance(pool, from, big.NewInt(0xffffffffffffff)) - tx = transaction(0, 100000, key) - if err := pool.AddRemote(tx); !errors.Is(err, ErrNonceTooLow) { - t.Error("expected", ErrNonceTooLow) - } - - tx = transaction(1, 100000, key) - pool.gasPrice = big.NewInt(1000) - if err := pool.AddRemote(tx); err != ErrUnderpriced { - t.Error("expected", ErrUnderpriced, "got", err) - } - if err := pool.AddLocal(tx); err != nil { - t.Error("expected", nil, "got", err) - } -} - -func TestTransactionQueue(t *testing.T) { - t.Parallel() - - pool, key := setupTxPool() - defer pool.Stop() - - tx := transaction(0, 100, key) - from, _ := deriveSender(tx) - testAddBalance(pool, from, big.NewInt(1000)) - <-pool.requestReset(nil, nil) - - pool.enqueueTx(tx.Hash(), tx, false, true) - <-pool.requestPromoteExecutables(newAccountSet(pool.signer, from)) - if len(pool.pending) != 1 { - t.Error("expected valid txs to be 1 is", len(pool.pending)) - } - - tx = transaction(1, 100, key) - from, _ = deriveSender(tx) - testSetNonce(pool, from, 2) - pool.enqueueTx(tx.Hash(), tx, false, true) - - <-pool.requestPromoteExecutables(newAccountSet(pool.signer, from)) - if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok { - t.Error("expected transaction to be in tx pool") - } - if len(pool.queue) > 0 { - t.Error("expected transaction queue to be empty. is", len(pool.queue)) - } -} - -func TestTransactionQueue2(t *testing.T) { - t.Parallel() - - pool, key := setupTxPool() - defer pool.Stop() - - tx1 := transaction(0, 100, key) - tx2 := transaction(10, 100, key) - tx3 := transaction(11, 100, key) - from, _ := deriveSender(tx1) - testAddBalance(pool, from, big.NewInt(1000)) - pool.reset(nil, nil) - - pool.enqueueTx(tx1.Hash(), tx1, false, true) - pool.enqueueTx(tx2.Hash(), tx2, false, true) - pool.enqueueTx(tx3.Hash(), tx3, false, true) - - pool.promoteExecutables([]common.Address{from}) - if len(pool.pending) != 1 { - t.Error("expected pending length to be 1, got", len(pool.pending)) - } - if pool.queue[from].Len() != 2 { - t.Error("expected len(queue) == 2, got", pool.queue[from].Len()) - } -} - -func TestTransactionNegativeValue(t *testing.T) { - t.Parallel() - - pool, key := setupTxPool() - defer pool.Stop() - - tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil), types.HomesteadSigner{}, key) - from, _ := deriveSender(tx) - testAddBalance(pool, from, big.NewInt(1)) - if err := pool.AddRemote(tx); err != ErrNegativeValue { - t.Error("expected", ErrNegativeValue, "got", err) - } -} - -func TestTransactionTipAboveFeeCap(t *testing.T) { - t.Parallel() - - pool, key := setupTxPoolWithConfig(eip1559Config) - defer pool.Stop() - - tx := dynamicFeeTx(0, 100, big.NewInt(1), big.NewInt(2), key) - - if err := pool.AddRemote(tx); err != ErrTipAboveFeeCap { - t.Error("expected", ErrTipAboveFeeCap, "got", err) - } -} - -func TestTransactionVeryHighValues(t *testing.T) { - t.Parallel() - - pool, key := setupTxPoolWithConfig(eip1559Config) - defer pool.Stop() - - veryBigNumber := big.NewInt(1) - veryBigNumber.Lsh(veryBigNumber, 300) - - tx := dynamicFeeTx(0, 100, big.NewInt(1), veryBigNumber, key) - if err := pool.AddRemote(tx); err != ErrTipVeryHigh { - t.Error("expected", ErrTipVeryHigh, "got", err) - } - - tx2 := dynamicFeeTx(0, 100, veryBigNumber, big.NewInt(1), key) - if err := pool.AddRemote(tx2); err != ErrFeeCapVeryHigh { - t.Error("expected", ErrFeeCapVeryHigh, "got", err) - } -} - -func TestTransactionChainFork(t *testing.T) { - t.Parallel() - - pool, key := setupTxPool() - defer pool.Stop() - - addr := crypto.PubkeyToAddress(key.PublicKey) - resetState := func() { - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - statedb.AddBalance(addr, big.NewInt(100000000000000)) - - pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} - <-pool.requestReset(nil, nil) - } - resetState() - - tx := transaction(0, 100000, key) - if _, err := pool.add(tx, false); err != nil { - t.Error("didn't expect error", err) - } - pool.removeTx(tx.Hash(), true) - - // reset the pool's internal state - resetState() - if _, err := pool.add(tx, false); err != nil { - t.Error("didn't expect error", err) - } -} - -func TestTransactionDoubleNonce(t *testing.T) { - t.Parallel() - - pool, key := setupTxPool() - defer pool.Stop() - - addr := crypto.PubkeyToAddress(key.PublicKey) - resetState := func() { - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - statedb.AddBalance(addr, big.NewInt(100000000000000)) - - pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} - <-pool.requestReset(nil, nil) - } - resetState() - - signer := types.HomesteadSigner{} - tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), nil), signer, key) - tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(2), nil), signer, key) - tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(1), nil), signer, key) - - // Add the first two transaction, ensure higher priced stays only - if replace, err := pool.add(tx1, false); err != nil || replace { - t.Errorf("first transaction insert failed (%v) or reported replacement (%v)", err, replace) - } - if replace, err := pool.add(tx2, false); err != nil || !replace { - t.Errorf("second transaction insert failed (%v) or not reported replacement (%v)", err, replace) - } - <-pool.requestPromoteExecutables(newAccountSet(signer, addr)) - if pool.pending[addr].Len() != 1 { - t.Error("expected 1 pending transactions, got", pool.pending[addr].Len()) - } - if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() { - t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash()) - } - - // Add the third transaction and ensure it's not saved (smaller price) - pool.add(tx3, false) - <-pool.requestPromoteExecutables(newAccountSet(signer, addr)) - if pool.pending[addr].Len() != 1 { - t.Error("expected 1 pending transactions, got", pool.pending[addr].Len()) - } - if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() { - t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash()) - } - // Ensure the total transaction count is correct - if pool.all.Count() != 1 { - t.Error("expected 1 total transactions, got", pool.all.Count()) - } -} - -func TestTransactionMissingNonce(t *testing.T) { - t.Parallel() - - pool, key := setupTxPool() - defer pool.Stop() - - addr := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, addr, big.NewInt(100000000000000)) - tx := transaction(1, 100000, key) - if _, err := pool.add(tx, false); err != nil { - t.Error("didn't expect error", err) - } - if len(pool.pending) != 0 { - t.Error("expected 0 pending transactions, got", len(pool.pending)) - } - if pool.queue[addr].Len() != 1 { - t.Error("expected 1 queued transaction, got", pool.queue[addr].Len()) - } - if pool.all.Count() != 1 { - t.Error("expected 1 total transactions, got", pool.all.Count()) - } -} - -func TestTransactionNonceRecovery(t *testing.T) { - t.Parallel() - - const n = 10 - pool, key := setupTxPool() - defer pool.Stop() - - addr := crypto.PubkeyToAddress(key.PublicKey) - testSetNonce(pool, addr, n) - testAddBalance(pool, addr, big.NewInt(100000000000000)) - <-pool.requestReset(nil, nil) - - tx := transaction(n, 100000, key) - if err := pool.AddRemote(tx); err != nil { - t.Error(err) - } - // simulate some weird re-order of transactions and missing nonce(s) - testSetNonce(pool, addr, n-1) - <-pool.requestReset(nil, nil) - if fn := pool.Nonce(addr); fn != n-1 { - t.Errorf("expected nonce to be %d, got %d", n-1, fn) - } -} - -// Tests that if an account runs out of funds, any pending and queued transactions -// are dropped. -func TestTransactionDropping(t *testing.T) { - t.Parallel() - - // Create a test account and fund it - pool, key := setupTxPool() - defer pool.Stop() - - account := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, account, big.NewInt(1000)) - - // Add some pending and some queued transactions - var ( - tx0 = transaction(0, 100, key) - tx1 = transaction(1, 200, key) - tx2 = transaction(2, 300, key) - tx10 = transaction(10, 100, key) - tx11 = transaction(11, 200, key) - tx12 = transaction(12, 300, key) - ) - pool.all.Add(tx0, false) - pool.priced.Put(tx0, false) - pool.promoteTx(account, tx0.Hash(), tx0) - - pool.all.Add(tx1, false) - pool.priced.Put(tx1, false) - pool.promoteTx(account, tx1.Hash(), tx1) - - pool.all.Add(tx2, false) - pool.priced.Put(tx2, false) - pool.promoteTx(account, tx2.Hash(), tx2) - - pool.enqueueTx(tx10.Hash(), tx10, false, true) - pool.enqueueTx(tx11.Hash(), tx11, false, true) - pool.enqueueTx(tx12.Hash(), tx12, false, true) - - // Check that pre and post validations leave the pool as is - if pool.pending[account].Len() != 3 { - t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) - } - if pool.queue[account].Len() != 3 { - t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) - } - if pool.all.Count() != 6 { - t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) - } - <-pool.requestReset(nil, nil) - if pool.pending[account].Len() != 3 { - t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) - } - if pool.queue[account].Len() != 3 { - t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) - } - if pool.all.Count() != 6 { - t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) - } - // Reduce the balance of the account, and check that invalidated transactions are dropped - testAddBalance(pool, account, big.NewInt(-650)) - <-pool.requestReset(nil, nil) - - if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { - t.Errorf("funded pending transaction missing: %v", tx0) - } - if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; !ok { - t.Errorf("funded pending transaction missing: %v", tx0) - } - if _, ok := pool.pending[account].txs.items[tx2.Nonce()]; ok { - t.Errorf("out-of-fund pending transaction present: %v", tx1) - } - if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { - t.Errorf("funded queued transaction missing: %v", tx10) - } - if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; !ok { - t.Errorf("funded queued transaction missing: %v", tx10) - } - if _, ok := pool.queue[account].txs.items[tx12.Nonce()]; ok { - t.Errorf("out-of-fund queued transaction present: %v", tx11) - } - if pool.all.Count() != 4 { - t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 4) - } - // Reduce the block gas limit, check that invalidated transactions are dropped - pool.chain.(*testBlockChain).gasLimit = 100 - <-pool.requestReset(nil, nil) - - if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { - t.Errorf("funded pending transaction missing: %v", tx0) - } - if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok { - t.Errorf("over-gased pending transaction present: %v", tx1) - } - if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { - t.Errorf("funded queued transaction missing: %v", tx10) - } - if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok { - t.Errorf("over-gased queued transaction present: %v", tx11) - } - if pool.all.Count() != 2 { - t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 2) - } -} - -// Tests that if a transaction is dropped from the current pending pool (e.g. out -// of fund), all consecutive (still valid, but not executable) transactions are -// postponed back into the future queue to prevent broadcasting them. -func TestTransactionPostponing(t *testing.T) { - t.Parallel() - - // Create the pool to test the postponing with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Create two test accounts to produce different gap profiles with - keys := make([]*ecdsa.PrivateKey, 2) - accs := make([]common.Address, len(keys)) - - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - accs[i] = crypto.PubkeyToAddress(keys[i].PublicKey) - - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(50100)) - } - // Add a batch consecutive pending transactions for validation - txs := []*types.Transaction{} - for i, key := range keys { - - for j := 0; j < 100; j++ { - var tx *types.Transaction - if (i+j)%2 == 0 { - tx = transaction(uint64(j), 25000, key) - } else { - tx = transaction(uint64(j), 50000, key) - } - txs = append(txs, tx) - } - } - for i, err := range pool.AddRemotesSync(txs) { - if err != nil { - t.Fatalf("tx %d: failed to add transactions: %v", i, err) - } - } - // Check that pre and post validations leave the pool as is - if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) { - t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs)) - } - if len(pool.queue) != 0 { - t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) - } - if pool.all.Count() != len(txs) { - t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) - } - <-pool.requestReset(nil, nil) - if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) { - t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs)) - } - if len(pool.queue) != 0 { - t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) - } - if pool.all.Count() != len(txs) { - t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) - } - // Reduce the balance of the account, and check that transactions are reorganised - for _, addr := range accs { - testAddBalance(pool, addr, big.NewInt(-1)) - } - <-pool.requestReset(nil, nil) - - // The first account's first transaction remains valid, check that subsequent - // ones are either filtered out, or queued up for later. - if _, ok := pool.pending[accs[0]].txs.items[txs[0].Nonce()]; !ok { - t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txs[0]) - } - if _, ok := pool.queue[accs[0]].txs.items[txs[0].Nonce()]; ok { - t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txs[0]) - } - for i, tx := range txs[1:100] { - if i%2 == 1 { - if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok { - t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx) - } - if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; !ok { - t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx) - } - } else { - if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok { - t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx) - } - if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; ok { - t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx) - } - } - } - // The second account's first transaction got invalid, check that all transactions - // are either filtered out, or queued up for later. - if pool.pending[accs[1]] != nil { - t.Errorf("invalidated account still has pending transactions") - } - for i, tx := range txs[100:] { - if i%2 == 1 { - if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; !ok { - t.Errorf("tx %d: valid but future transaction missing from future queue: %v", 100+i, tx) - } - } else { - if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; ok { - t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", 100+i, tx) - } - } - } - if pool.all.Count() != len(txs)/2 { - t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)/2) - } -} - -// Tests that if the transaction pool has both executable and non-executable -// transactions from an origin account, filling the nonce gap moves all queued -// ones into the pending pool. -func TestTransactionGapFilling(t *testing.T) { - t.Parallel() - - // Create a test account and fund it - pool, key := setupTxPool() - defer pool.Stop() - - account := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, account, big.NewInt(1000000)) - - // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsNotify, testTxPoolConfig.AccountQueue+5) - sub := pool.txFeed.Subscribe(events) - defer sub.Unsubscribe() - - // Create a pending and a queued transaction with a nonce-gap in between - pool.AddRemotesSync([]*types.Transaction{ - transaction(0, 100000, key), - transaction(2, 100000, key), - }) - pending, queued := pool.Stats() - if pending != 1 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) - } - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - if err := validateEvents(events, 1); err != nil { - t.Fatalf("original event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Fill the nonce gap and ensure all transactions become pending - if err := pool.addRemoteSync(transaction(1, 100000, key)); err != nil { - t.Fatalf("failed to add gapped transaction: %v", err) - } - pending, queued = pool.Stats() - if pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if err := validateEvents(events, 2); err != nil { - t.Fatalf("gap-filling event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that if the transaction count belonging to a single account goes above -// some threshold, the higher transactions are dropped to prevent DOS attacks. -func TestTransactionQueueAccountLimiting(t *testing.T) { - t.Parallel() - - // Create a test account and fund it - pool, key := setupTxPool() - defer pool.Stop() - - account := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, account, big.NewInt(1000000)) - - // Keep queuing up transactions and make sure all above a limit are dropped - for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ { - if err := pool.addRemoteSync(transaction(i, 100000, key)); err != nil { - t.Fatalf("tx %d: failed to add transaction: %v", i, err) - } - if len(pool.pending) != 0 { - t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, len(pool.pending), 0) - } - if i <= testTxPoolConfig.AccountQueue { - if pool.queue[account].Len() != int(i) { - t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), i) - } - } else { - if pool.queue[account].Len() != int(testTxPoolConfig.AccountQueue) { - t.Errorf("tx %d: queue limit mismatch: have %d, want %d", i, pool.queue[account].Len(), testTxPoolConfig.AccountQueue) - } - } - } - if pool.all.Count() != int(testTxPoolConfig.AccountQueue) { - t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue) - } -} - -// Tests that if the transaction count belonging to multiple accounts go above -// some threshold, the higher transactions are dropped to prevent DOS attacks. -// -// This logic should not hold for local transactions, unless the local tracking -// mechanism is disabled. -func TestTransactionQueueGlobalLimiting(t *testing.T) { - testTransactionQueueGlobalLimiting(t, false) -} -func TestTransactionQueueGlobalLimitingNoLocals(t *testing.T) { - testTransactionQueueGlobalLimiting(t, true) -} - -func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { - t.Parallel() - - // Create the pool to test the limit enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - config := testTxPoolConfig - config.NoLocals = nolocals - config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible) - - pool := NewTxPool(config, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Create a number of test accounts and fund them (last one will be the local) - keys := make([]*ecdsa.PrivateKey, 5) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) - } - local := keys[len(keys)-1] - - // Generate and queue a batch of transactions - nonces := make(map[common.Address]uint64) - - txs := make(types.Transactions, 0, 3*config.GlobalQueue) - for len(txs) < cap(txs) { - key := keys[rand.Intn(len(keys)-1)] // skip adding transactions with the local account - addr := crypto.PubkeyToAddress(key.PublicKey) - - txs = append(txs, transaction(nonces[addr]+1, 100000, key)) - nonces[addr]++ - } - // Import the batch and verify that limits have been enforced - pool.AddRemotesSync(txs) - - queued := 0 - for addr, list := range pool.queue { - if list.Len() > int(config.AccountQueue) { - t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) - } - queued += list.Len() - } - if queued > int(config.GlobalQueue) { - t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) - } - // Generate a batch of transactions from the local account and import them - txs = txs[:0] - for i := uint64(0); i < 3*config.GlobalQueue; i++ { - txs = append(txs, transaction(i+1, 100000, local)) - } - pool.AddLocals(txs) - - // If locals are disabled, the previous eviction algorithm should apply here too - if nolocals { - queued := 0 - for addr, list := range pool.queue { - if list.Len() > int(config.AccountQueue) { - t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) - } - queued += list.Len() - } - if queued > int(config.GlobalQueue) { - t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) - } - } else { - // Local exemptions are enabled, make sure the local account owned the queue - if len(pool.queue) != 1 { - t.Errorf("multiple accounts in queue: have %v, want %v", len(pool.queue), 1) - } - // Also ensure no local transactions are ever dropped, even if above global limits - if queued := pool.queue[crypto.PubkeyToAddress(local.PublicKey)].Len(); uint64(queued) != 3*config.GlobalQueue { - t.Fatalf("local account queued transaction count mismatch: have %v, want %v", queued, 3*config.GlobalQueue) - } - } -} - -// Tests that if an account remains idle for a prolonged amount of time, any -// non-executable transactions queued up are dropped to prevent wasting resources -// on shuffling them around. -// -// This logic should not hold for local transactions, unless the local tracking -// mechanism is disabled. -func TestTransactionQueueTimeLimiting(t *testing.T) { - testTransactionQueueTimeLimiting(t, false) -} -func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { - testTransactionQueueTimeLimiting(t, true) -} - -func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { - // Reduce the eviction interval to a testable amount - defer func(old time.Duration) { evictionInterval = old }(evictionInterval) - evictionInterval = time.Millisecond * 100 - - // Create the pool to test the non-expiration enforcement - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - config := testTxPoolConfig - config.Lifetime = time.Second - config.NoLocals = nolocals - - pool := NewTxPool(config, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Create two test accounts to ensure remotes expire but locals do not - local, _ := crypto.GenerateKey() - remote, _ := crypto.GenerateKey() - - testAddBalance(pool, crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) - testAddBalance(pool, crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) - - // Add the two transactions and ensure they both are queued up - if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add local transaction: %v", err) - } - if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), remote)); err != nil { - t.Fatalf("failed to add remote transaction: %v", err) - } - pending, queued := pool.Stats() - if pending != 0 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) - } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - - // Allow the eviction interval to run - time.Sleep(2 * evictionInterval) - - // Transactions should not be evicted from the queue yet since lifetime duration has not passed - pending, queued = pool.Stats() - if pending != 0 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) - } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - - // Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains - time.Sleep(2 * config.Lifetime) - - pending, queued = pool.Stats() - if pending != 0 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) - } - if nolocals { - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - } else { - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - - // remove current transactions and increase nonce to prepare for a reset and cleanup - statedb.SetNonce(crypto.PubkeyToAddress(remote.PublicKey), 2) - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2) - <-pool.requestReset(nil, nil) - - // make sure queue, pending are cleared - pending, queued = pool.Stats() - if pending != 0 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) - } - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - - // Queue gapped transactions - if err := pool.AddLocal(pricedTransaction(4, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add remote transaction: %v", err) - } - if err := pool.addRemoteSync(pricedTransaction(4, 100000, big.NewInt(1), remote)); err != nil { - t.Fatalf("failed to add remote transaction: %v", err) - } - time.Sleep(5 * evictionInterval) // A half lifetime pass - - // Queue executable transactions, the life cycle should be restarted. - if err := pool.AddLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add remote transaction: %v", err) - } - if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), remote)); err != nil { - t.Fatalf("failed to add remote transaction: %v", err) - } - time.Sleep(6 * evictionInterval) - - // All gapped transactions shouldn't be kicked out - pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - - // The whole life time pass after last promotion, kick out stale transactions - time.Sleep(2 * config.Lifetime) - pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - if nolocals { - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - } else { - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that even if the transaction count belonging to a single account goes -// above some threshold, as long as the transactions are executable, they are -// accepted. -func TestTransactionPendingLimiting(t *testing.T) { - t.Parallel() - - // Create a test account and fund it - pool, key := setupTxPool() - defer pool.Stop() - - account := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, account, big.NewInt(1000000)) - - // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsNotify, testTxPoolConfig.AccountQueue+5) - sub := pool.txFeed.Subscribe(events) - defer sub.Unsubscribe() - - // Keep queuing up transactions and make sure all above a limit are dropped - for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { - if err := pool.addRemoteSync(transaction(i, 100000, key)); err != nil { - t.Fatalf("tx %d: failed to add transaction: %v", i, err) - } - if pool.pending[account].Len() != int(i)+1 { - t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, pool.pending[account].Len(), i+1) - } - if len(pool.queue) != 0 { - t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), 0) - } - } - if pool.all.Count() != int(testTxPoolConfig.AccountQueue+5) { - t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue+5) - } - if err := validateEvents(events, int(testTxPoolConfig.AccountQueue+5)); err != nil { - t.Fatalf("event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that if the transaction count belonging to multiple accounts go above -// some hard threshold, the higher transactions are dropped to prevent DOS -// attacks. -func TestTransactionPendingGlobalLimiting(t *testing.T) { - t.Parallel() - - // Create the pool to test the limit enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - config := testTxPoolConfig - config.GlobalSlots = config.AccountSlots * 10 - - pool := NewTxPool(config, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 5) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) - } - // Generate and queue a batch of transactions - nonces := make(map[common.Address]uint64) - - txs := types.Transactions{} - for _, key := range keys { - addr := crypto.PubkeyToAddress(key.PublicKey) - for j := 0; j < int(config.GlobalSlots)/len(keys)*2; j++ { - txs = append(txs, transaction(nonces[addr], 100000, key)) - nonces[addr]++ - } - } - // Import the batch and verify that limits have been enforced - pool.AddRemotesSync(txs) - - pending := 0 - for _, list := range pool.pending { - pending += list.Len() - } - if pending > int(config.GlobalSlots) { - t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, config.GlobalSlots) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Test the limit on transaction size is enforced correctly. -// This test verifies every transaction having allowed size -// is added to the pool, and longer transactions are rejected. -func TestTransactionAllowedTxSize(t *testing.T) { - t.Parallel() - - // Create a test account and fund it - pool, key := setupTxPool() - defer pool.Stop() - - account := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, account, big.NewInt(1000000000)) - - // Compute maximal data size for transactions (lower bound). - // - // It is assumed the fields in the transaction (except of the data) are: - // - nonce <= 32 bytes - // - gasPrice <= 32 bytes - // - gasLimit <= 32 bytes - // - recipient == 20 bytes - // - value <= 32 bytes - // - signature == 65 bytes - // All those fields are summed up to at most 213 bytes. - baseSize := uint64(213) - dataSize := txMaxSize - baseSize - - // Try adding a transaction with maximal allowed size - tx := pricedDataTransaction(0, pool.currentMaxGas, big.NewInt(1), key, dataSize) - if err := pool.addRemoteSync(tx); err != nil { - t.Fatalf("failed to add transaction of size %d, close to maximal: %v", int(tx.Size()), err) - } - // Try adding a transaction with random allowed size - if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentMaxGas, big.NewInt(1), key, uint64(rand.Intn(int(dataSize))))); err != nil { - t.Fatalf("failed to add transaction of random allowed size: %v", err) - } - // Try adding a transaction of minimal not allowed size - if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentMaxGas, big.NewInt(1), key, txMaxSize)); err == nil { - t.Fatalf("expected rejection on slightly oversize transaction") - } - // Try adding a transaction of random not allowed size - if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentMaxGas, big.NewInt(1), key, dataSize+1+uint64(rand.Intn(10*txMaxSize)))); err == nil { - t.Fatalf("expected rejection on oversize transaction") - } - // Run some sanity checks on the pool internals - pending, queued := pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that if transactions start being capped, transactions are also removed from 'all' -func TestTransactionCapClearsFromAll(t *testing.T) { - t.Parallel() - - // Create the pool to test the limit enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - config := testTxPoolConfig - config.AccountSlots = 2 - config.AccountQueue = 2 - config.GlobalSlots = 8 - - pool := NewTxPool(config, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Create a number of test accounts and fund them - key, _ := crypto.GenerateKey() - addr := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, addr, big.NewInt(1000000)) - - txs := types.Transactions{} - for j := 0; j < int(config.GlobalSlots)*2; j++ { - txs = append(txs, transaction(uint64(j), 100000, key)) - } - // Import the batch and verify that limits have been enforced - pool.AddRemotes(txs) - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that if the transaction count belonging to multiple accounts go above -// some hard threshold, if they are under the minimum guaranteed slot count then -// the transactions are still kept. -func TestTransactionPendingMinimumAllowance(t *testing.T) { - t.Parallel() - - // Create the pool to test the limit enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - config := testTxPoolConfig - config.GlobalSlots = 1 - - pool := NewTxPool(config, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 5) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) - } - // Generate and queue a batch of transactions - nonces := make(map[common.Address]uint64) - - txs := types.Transactions{} - for _, key := range keys { - addr := crypto.PubkeyToAddress(key.PublicKey) - for j := 0; j < int(config.AccountSlots)*2; j++ { - txs = append(txs, transaction(nonces[addr], 100000, key)) - nonces[addr]++ - } - } - // Import the batch and verify that limits have been enforced - pool.AddRemotesSync(txs) - - for addr, list := range pool.pending { - if list.Len() != int(config.AccountSlots) { - t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), config.AccountSlots) - } - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that setting the transaction pool gas price to a higher value correctly -// discards everything cheaper than that and moves any gapped transactions back -// from the pending pool to the queue. -// -// Note, local transactions are never allowed to be dropped. -func TestTransactionPoolRepricing(t *testing.T) { - t.Parallel() - - // Create the pool to test the pricing enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsNotify, 32) - sub := pool.txFeed.Subscribe(events) - defer sub.Unsubscribe() - - // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 4) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) - } - // Generate and queue a batch of transactions, both pending and queued - txs := types.Transactions{} - - txs = append(txs, pricedTransaction(0, 100000, big.NewInt(2), keys[0])) - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[0])) - txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[0])) - - txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[1])) - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[1])) - txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[1])) - - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[2])) - txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2])) - txs = append(txs, pricedTransaction(3, 100000, big.NewInt(2), keys[2])) - - ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[3]) - - // Import the batch and that both pending and queued transactions match up - pool.AddRemotesSync(txs) - pool.AddLocal(ltx) - - pending, queued := pool.Stats() - if pending != 7 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 7) - } - if queued != 3 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) - } - if err := validateEvents(events, 7); err != nil { - t.Fatalf("original event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Reprice the pool and check that underpriced transactions get dropped - pool.SetGasPrice(big.NewInt(2)) - - pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - if queued != 5 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 5) - } - if err := validateEvents(events, 0); err != nil { - t.Fatalf("reprice event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Check that we can't add the old transactions back - if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), keys[0])); err != ErrUnderpriced { - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) - } - if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced { - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) - } - if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), keys[2])); err != ErrUnderpriced { - t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced) - } - if err := validateEvents(events, 0); err != nil { - t.Fatalf("post-reprice event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // However we can add local underpriced transactions - tx := pricedTransaction(1, 100000, big.NewInt(1), keys[3]) - if err := pool.AddLocal(tx); err != nil { - t.Fatalf("failed to add underpriced local transaction: %v", err) - } - if pending, _ = pool.Stats(); pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if err := validateEvents(events, 1); err != nil { - t.Fatalf("post-reprice local event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // And we can fill gaps with properly priced transactions - if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(2), keys[0])); err != nil { - t.Fatalf("failed to add pending transaction: %v", err) - } - if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(2), keys[1])); err != nil { - t.Fatalf("failed to add pending transaction: %v", err) - } - if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(2), keys[2])); err != nil { - t.Fatalf("failed to add queued transaction: %v", err) - } - if err := validateEvents(events, 5); err != nil { - t.Fatalf("post-reprice event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that setting the transaction pool gas price to a higher value correctly -// discards everything cheaper (legacy & dynamic fee) than that and moves any -// gapped transactions back from the pending pool to the queue. -// -// Note, local transactions are never allowed to be dropped. -func TestTransactionPoolRepricingDynamicFee(t *testing.T) { - t.Parallel() - - // Create the pool to test the pricing enforcement with - pool, _ := setupTxPoolWithConfig(eip1559Config) - defer pool.Stop() - - // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsNotify, 32) - sub := pool.txFeed.Subscribe(events) - defer sub.Unsubscribe() - - // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 4) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) - } - // Generate and queue a batch of transactions, both pending and queued - txs := types.Transactions{} - - txs = append(txs, pricedTransaction(0, 100000, big.NewInt(2), keys[0])) - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[0])) - txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[0])) - - txs = append(txs, dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1])) - txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(3), big.NewInt(2), keys[1])) - txs = append(txs, dynamicFeeTx(2, 100000, big.NewInt(3), big.NewInt(2), keys[1])) - - txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(2), big.NewInt(2), keys[2])) - txs = append(txs, dynamicFeeTx(2, 100000, big.NewInt(1), big.NewInt(1), keys[2])) - txs = append(txs, dynamicFeeTx(3, 100000, big.NewInt(2), big.NewInt(2), keys[2])) - - ltx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[3]) - - // Import the batch and that both pending and queued transactions match up - pool.AddRemotesSync(txs) - pool.AddLocal(ltx) - - pending, queued := pool.Stats() - if pending != 7 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 7) - } - if queued != 3 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) - } - if err := validateEvents(events, 7); err != nil { - t.Fatalf("original event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Reprice the pool and check that underpriced transactions get dropped - pool.SetGasPrice(big.NewInt(2)) - - pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - if queued != 5 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 5) - } - if err := validateEvents(events, 0); err != nil { - t.Fatalf("reprice event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Check that we can't add the old transactions back - tx := pricedTransaction(1, 100000, big.NewInt(1), keys[0]) - if err := pool.AddRemote(tx); err != ErrUnderpriced { - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) - } - tx = dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1]) - if err := pool.AddRemote(tx); err != ErrUnderpriced { - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) - } - tx = dynamicFeeTx(2, 100000, big.NewInt(1), big.NewInt(1), keys[2]) - if err := pool.AddRemote(tx); err != ErrUnderpriced { - t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced) - } - if err := validateEvents(events, 0); err != nil { - t.Fatalf("post-reprice event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // However we can add local underpriced transactions - tx = dynamicFeeTx(1, 100000, big.NewInt(1), big.NewInt(1), keys[3]) - if err := pool.AddLocal(tx); err != nil { - t.Fatalf("failed to add underpriced local transaction: %v", err) - } - if pending, _ = pool.Stats(); pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if err := validateEvents(events, 1); err != nil { - t.Fatalf("post-reprice local event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // And we can fill gaps with properly priced transactions - tx = pricedTransaction(1, 100000, big.NewInt(2), keys[0]) - if err := pool.AddRemote(tx); err != nil { - t.Fatalf("failed to add pending transaction: %v", err) - } - tx = dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[1]) - if err := pool.AddRemote(tx); err != nil { - t.Fatalf("failed to add pending transaction: %v", err) - } - tx = dynamicFeeTx(2, 100000, big.NewInt(2), big.NewInt(2), keys[2]) - if err := pool.AddRemote(tx); err != nil { - t.Fatalf("failed to add queued transaction: %v", err) - } - if err := validateEvents(events, 5); err != nil { - t.Fatalf("post-reprice event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that setting the transaction pool gas price to a higher value does not -// remove local transactions (legacy & dynamic fee). -func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { - t.Parallel() - - // Create the pool to test the pricing enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain) - defer pool.Stop() - - // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 3) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000)) - } - // Create transaction (both pending and queued) with a linearly growing gasprice - for i := uint64(0); i < 500; i++ { - // Add pending transaction. - pendingTx := pricedTransaction(i, 100000, big.NewInt(int64(i)), keys[2]) - if err := pool.AddLocal(pendingTx); err != nil { - t.Fatal(err) - } - // Add queued transaction. - queuedTx := pricedTransaction(i+501, 100000, big.NewInt(int64(i)), keys[2]) - if err := pool.AddLocal(queuedTx); err != nil { - t.Fatal(err) - } - - // Add pending dynamic fee transaction. - pendingTx = dynamicFeeTx(i, 100000, big.NewInt(int64(i)+1), big.NewInt(int64(i)), keys[1]) - if err := pool.AddLocal(pendingTx); err != nil { - t.Fatal(err) - } - // Add queued dynamic fee transaction. - queuedTx = dynamicFeeTx(i+501, 100000, big.NewInt(int64(i)+1), big.NewInt(int64(i)), keys[1]) - if err := pool.AddLocal(queuedTx); err != nil { - t.Fatal(err) - } - } - pending, queued := pool.Stats() - expPending, expQueued := 1000, 1000 - validate := func() { - pending, queued = pool.Stats() - if pending != expPending { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, expPending) - } - if queued != expQueued { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, expQueued) - } - - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - } - validate() - - // Reprice the pool and check that nothing is dropped - pool.SetGasPrice(big.NewInt(2)) - validate() - - pool.SetGasPrice(big.NewInt(2)) - pool.SetGasPrice(big.NewInt(4)) - pool.SetGasPrice(big.NewInt(8)) - pool.SetGasPrice(big.NewInt(100)) - validate() -} - -// Tests that when the pool reaches its global transaction limit, underpriced -// transactions are gradually shifted out for more expensive ones and any gapped -// pending transactions are moved into the queue. -// -// Note, local transactions are never allowed to be dropped. -func TestTransactionPoolUnderpricing(t *testing.T) { - t.Parallel() - - // Create the pool to test the pricing enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - config := testTxPoolConfig - config.GlobalSlots = 2 - config.GlobalQueue = 2 - - pool := NewTxPool(config, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsNotify, 32) - sub := pool.txFeed.Subscribe(events) - defer sub.Unsubscribe() - - // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 4) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) - } - // Generate and queue a batch of transactions, both pending and queued - txs := types.Transactions{} - - txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0])) - - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[1])) - - ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[2]) - - // Import the batch and that both pending and queued transactions match up - pool.AddRemotes(txs) - pool.AddLocal(ltx) - - pending, queued := pool.Stats() - if pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - if err := validateEvents(events, 3); err != nil { - t.Fatalf("original event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Ensure that adding an underpriced transaction on block limit fails - if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced { - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) - } - // Ensure that adding high priced transactions drops cheap ones, but not own - if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { // +K1:0 => -K1:1 => Pend K0:0, K0:1, K1:0, K2:0; Que - - t.Fatalf("failed to add well priced transaction: %v", err) - } - if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(4), keys[1])); err != nil { // +K1:2 => -K0:0 => Pend K1:0, K2:0; Que K0:1 K1:2 - t.Fatalf("failed to add well priced transaction: %v", err) - } - if err := pool.AddRemote(pricedTransaction(3, 100000, big.NewInt(5), keys[1])); err != nil { // +K1:3 => -K0:1 => Pend K1:0, K2:0; Que K1:2 K1:3 - t.Fatalf("failed to add well priced transaction: %v", err) - } - pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) - } - if err := validateEvents(events, 1); err != nil { - t.Fatalf("additional event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Ensure that adding local transactions can push out even higher priced ones - ltx = pricedTransaction(1, 100000, big.NewInt(0), keys[2]) - if err := pool.AddLocal(ltx); err != nil { - t.Fatalf("failed to append underpriced local transaction: %v", err) - } - ltx = pricedTransaction(0, 100000, big.NewInt(0), keys[3]) - if err := pool.AddLocal(ltx); err != nil { - t.Fatalf("failed to add new underpriced local transaction: %v", err) - } - pending, queued = pool.Stats() - if pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - if err := validateEvents(events, 2); err != nil { - t.Fatalf("local event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that more expensive transactions push out cheap ones from the pool, but -// without producing instability by creating gaps that start jumping transactions -// back and forth between queued/pending. -func TestTransactionPoolStableUnderpricing(t *testing.T) { - t.Parallel() - - // Create the pool to test the pricing enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - config := testTxPoolConfig - config.GlobalSlots = 128 - config.GlobalQueue = 0 - - pool := NewTxPool(config, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsNotify, 32) - sub := pool.txFeed.Subscribe(events) - defer sub.Unsubscribe() - - // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 2) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) - } - // Fill up the entire queue with the same transaction price points - txs := types.Transactions{} - for i := uint64(0); i < config.GlobalSlots; i++ { - txs = append(txs, pricedTransaction(i, 100000, big.NewInt(1), keys[0])) - } - pool.AddRemotesSync(txs) - - pending, queued := pool.Stats() - if pending != int(config.GlobalSlots) { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) - } - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if err := validateEvents(events, int(config.GlobalSlots)); err != nil { - t.Fatalf("original event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Ensure that adding high priced transactions drops a cheap, but doesn't produce a gap - if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { - t.Fatalf("failed to add well priced transaction: %v", err) - } - pending, queued = pool.Stats() - if pending != int(config.GlobalSlots) { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) - } - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if err := validateEvents(events, 1); err != nil { - t.Fatalf("additional event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that when the pool reaches its global transaction limit, underpriced -// transactions (legacy & dynamic fee) are gradually shifted out for more -// expensive ones and any gapped pending transactions are moved into the queue. -// -// Note, local transactions are never allowed to be dropped. -func TestTransactionPoolUnderpricingDynamicFee(t *testing.T) { - t.Parallel() - - pool, _ := setupTxPoolWithConfig(eip1559Config) - defer pool.Stop() - - pool.config.GlobalSlots = 2 - pool.config.GlobalQueue = 2 - - // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsNotify, 32) - sub := pool.txFeed.Subscribe(events) - defer sub.Unsubscribe() - - // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 4) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) - } - - // Generate and queue a batch of transactions, both pending and queued - txs := types.Transactions{} - - txs = append(txs, dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[0])) - txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0])) - txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(2), big.NewInt(1), keys[1])) - - ltx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[2]) - - // Import the batch and that both pending and queued transactions match up - pool.AddRemotes(txs) // Pend K0:0, K0:1; Que K1:1 - pool.AddLocal(ltx) // +K2:0 => Pend K0:0, K0:1, K2:0; Que K1:1 - - pending, queued := pool.Stats() - if pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - if err := validateEvents(events, 3); err != nil { - t.Fatalf("original event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - - // Ensure that adding an underpriced transaction fails - tx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1]) - if err := pool.AddRemote(tx); err != ErrUnderpriced { // Pend K0:0, K0:1, K2:0; Que K1:1 - t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) - } - - // Ensure that adding high priced transactions drops cheap ones, but not own - tx = pricedTransaction(0, 100000, big.NewInt(2), keys[1]) - if err := pool.AddRemote(tx); err != nil { // +K1:0, -K1:1 => Pend K0:0, K0:1, K1:0, K2:0; Que - - t.Fatalf("failed to add well priced transaction: %v", err) - } - - tx = pricedTransaction(2, 100000, big.NewInt(3), keys[1]) - if err := pool.AddRemote(tx); err != nil { // +K1:2, -K0:1 => Pend K0:0 K1:0, K2:0; Que K1:2 - t.Fatalf("failed to add well priced transaction: %v", err) - } - tx = dynamicFeeTx(3, 100000, big.NewInt(4), big.NewInt(1), keys[1]) - if err := pool.AddRemote(tx); err != nil { // +K1:3, -K1:0 => Pend K0:0 K2:0; Que K1:2 K1:3 - t.Fatalf("failed to add well priced transaction: %v", err) - } - pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) - } - if err := validateEvents(events, 1); err != nil { - t.Fatalf("additional event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Ensure that adding local transactions can push out even higher priced ones - ltx = dynamicFeeTx(1, 100000, big.NewInt(0), big.NewInt(0), keys[2]) - if err := pool.AddLocal(ltx); err != nil { - t.Fatalf("failed to append underpriced local transaction: %v", err) - } - ltx = dynamicFeeTx(0, 100000, big.NewInt(0), big.NewInt(0), keys[3]) - if err := pool.AddLocal(ltx); err != nil { - t.Fatalf("failed to add new underpriced local transaction: %v", err) - } - pending, queued = pool.Stats() - if pending != 3 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) - } - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - if err := validateEvents(events, 2); err != nil { - t.Fatalf("local event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests whether highest fee cap transaction is retained after a batch of high effective -// tip transactions are added and vice versa -func TestDualHeapEviction(t *testing.T) { - t.Parallel() - - pool, _ := setupTxPoolWithConfig(eip1559Config) - defer pool.Stop() - - pool.config.GlobalSlots = 10 - pool.config.GlobalQueue = 10 - - var ( - highTip, highCap *types.Transaction - baseFee int - ) - - check := func(tx *types.Transaction, name string) { - if pool.all.GetRemote(tx.Hash()) == nil { - t.Fatalf("highest %s transaction evicted from the pool", name) - } - } - - add := func(urgent bool) { - txs := make([]*types.Transaction, 20) - for i := range txs { - // Create a test accounts and fund it - key, _ := crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000000)) - if urgent { - txs[i] = dynamicFeeTx(0, 100000, big.NewInt(int64(baseFee+1+i)), big.NewInt(int64(1+i)), key) - highTip = txs[i] - } else { - txs[i] = dynamicFeeTx(0, 100000, big.NewInt(int64(baseFee+200+i)), big.NewInt(1), key) - highCap = txs[i] - } - } - pool.AddRemotes(txs) - pending, queued := pool.Stats() - if pending+queued != 20 { - t.Fatalf("transaction count mismatch: have %d, want %d", pending+queued, 10) - } - } - - add(false) - for baseFee = 0; baseFee <= 1000; baseFee += 100 { - pool.priced.SetBaseFee(big.NewInt(int64(baseFee))) - add(true) - check(highCap, "fee cap") - add(false) - check(highTip, "effective tip") - } - - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that the pool rejects duplicate transactions. -func TestTransactionDeduplication(t *testing.T) { - t.Parallel() - - // Create the pool to test the pricing enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Create a test account to add transactions with - key, _ := crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000)) - - // Create a batch of transactions and add a few of them - txs := make([]*types.Transaction, 16) - for i := 0; i < len(txs); i++ { - txs[i] = pricedTransaction(uint64(i), 100000, big.NewInt(1), key) - } - var firsts []*types.Transaction - for i := 0; i < len(txs); i += 2 { - firsts = append(firsts, txs[i]) - } - errs := pool.AddRemotesSync(firsts) - if len(errs) != len(firsts) { - t.Fatalf("first add mismatching result count: have %d, want %d", len(errs), len(firsts)) - } - for i, err := range errs { - if err != nil { - t.Errorf("add %d failed: %v", i, err) - } - } - pending, queued := pool.Stats() - if pending != 1 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) - } - if queued != len(txs)/2-1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, len(txs)/2-1) - } - // Try to add all of them now and ensure previous ones error out as knowns - errs = pool.AddRemotesSync(txs) - if len(errs) != len(txs) { - t.Fatalf("all add mismatching result count: have %d, want %d", len(errs), len(txs)) - } - for i, err := range errs { - if i%2 == 0 && err == nil { - t.Errorf("add %d succeeded, should have failed as known", i) - } - if i%2 == 1 && err != nil { - t.Errorf("add %d failed: %v", i, err) - } - } - pending, queued = pool.Stats() - if pending != len(txs) { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, len(txs)) - } - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that the pool rejects replacement transactions that don't meet the minimum -// price bump required. -func TestTransactionReplacement(t *testing.T) { - t.Parallel() - - // Create the pool to test the pricing enforcement with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsNotify, 32) - sub := pool.txFeed.Subscribe(events) - defer sub.Unsubscribe() - - // Create a test account to add transactions with - key, _ := crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000)) - - // Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too) - price := int64(100) - threshold := (price * (100 + int64(testTxPoolConfig.PriceBump))) / 100 - - if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), key)); err != nil { - t.Fatalf("failed to add original cheap pending transaction: %v", err) - } - if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced { - t.Fatalf("original cheap pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) - } - if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(2), key)); err != nil { - t.Fatalf("failed to replace original cheap pending transaction: %v", err) - } - if err := validateEvents(events, 2); err != nil { - t.Fatalf("cheap replacement event firing failed: %v", err) - } - - if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(price), key)); err != nil { - t.Fatalf("failed to add original proper pending transaction: %v", err) - } - if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { - t.Fatalf("original proper pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) - } - if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(threshold), key)); err != nil { - t.Fatalf("failed to replace original proper pending transaction: %v", err) - } - if err := validateEvents(events, 2); err != nil { - t.Fatalf("proper replacement event firing failed: %v", err) - } - - // Add queued transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too) - if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), key)); err != nil { - t.Fatalf("failed to add original cheap queued transaction: %v", err) - } - if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced { - t.Fatalf("original cheap queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) - } - if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(2), key)); err != nil { - t.Fatalf("failed to replace original cheap queued transaction: %v", err) - } - - if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(price), key)); err != nil { - t.Fatalf("failed to add original proper queued transaction: %v", err) - } - if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { - t.Fatalf("original proper queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) - } - if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(threshold), key)); err != nil { - t.Fatalf("failed to replace original proper queued transaction: %v", err) - } - - if err := validateEvents(events, 0); err != nil { - t.Fatalf("queued replacement event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that the pool rejects replacement dynamic fee transactions that don't -// meet the minimum price bump required. -func TestTransactionReplacementDynamicFee(t *testing.T) { - t.Parallel() - - // Create the pool to test the pricing enforcement with - pool, key := setupTxPoolWithConfig(eip1559Config) - defer pool.Stop() - testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000)) - - // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsNotify, 32) - sub := pool.txFeed.Subscribe(events) - defer sub.Unsubscribe() - - // Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too) - gasFeeCap := int64(100) - feeCapThreshold := (gasFeeCap * (100 + int64(testTxPoolConfig.PriceBump))) / 100 - gasTipCap := int64(60) - tipThreshold := (gasTipCap * (100 + int64(testTxPoolConfig.PriceBump))) / 100 - - // Run the following identical checks for both the pending and queue pools: - // 1. Send initial tx => accept - // 2. Don't bump tip or fee cap => discard - // 3. Bump both more than min => accept - // 4. Check events match expected (2 new executable txs during pending, 0 during queue) - // 5. Send new tx with larger tip and gasFeeCap => accept - // 6. Bump tip max allowed so it's still underpriced => discard - // 7. Bump fee cap max allowed so it's still underpriced => discard - // 8. Bump tip min for acceptance => discard - // 9. Bump feecap min for acceptance => discard - // 10. Bump feecap and tip min for acceptance => accept - // 11. Check events match expected (2 new executable txs during pending, 0 during queue) - stages := []string{"pending", "queued"} - for _, stage := range stages { - // Since state is empty, 0 nonce txs are "executable" and can go - // into pending immediately. 2 nonce txs are "happed - nonce := uint64(0) - if stage == "queued" { - nonce = 2 - } - - // 1. Send initial tx => accept - tx := dynamicFeeTx(nonce, 100000, big.NewInt(2), big.NewInt(1), key) - if err := pool.addRemoteSync(tx); err != nil { - t.Fatalf("failed to add original cheap %s transaction: %v", stage, err) - } - // 2. Don't bump tip or feecap => discard - tx = dynamicFeeTx(nonce, 100001, big.NewInt(2), big.NewInt(1), key) - if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced { - t.Fatalf("original cheap %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced) - } - // 3. Bump both more than min => accept - tx = dynamicFeeTx(nonce, 100000, big.NewInt(3), big.NewInt(2), key) - if err := pool.AddRemote(tx); err != nil { - t.Fatalf("failed to replace original cheap %s transaction: %v", stage, err) - } - // 4. Check events match expected (2 new executable txs during pending, 0 during queue) - count := 2 - if stage == "queued" { - count = 0 - } - if err := validateEvents(events, count); err != nil { - t.Fatalf("cheap %s replacement event firing failed: %v", stage, err) - } - // 5. Send new tx with larger tip and feeCap => accept - tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(gasTipCap), key) - if err := pool.addRemoteSync(tx); err != nil { - t.Fatalf("failed to add original proper %s transaction: %v", stage, err) - } - // 6. Bump tip max allowed so it's still underpriced => discard - tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold-1), key) - if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced { - t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced) - } - // 7. Bump fee cap max allowed so it's still underpriced => discard - tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold-1), big.NewInt(gasTipCap), key) - if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced { - t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced) - } - // 8. Bump tip min for acceptance => accept - tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold), key) - if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced { - t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced) - } - // 9. Bump fee cap min for acceptance => accept - tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(gasTipCap), key) - if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced { - t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced) - } - // 10. Check events match expected (3 new executable txs during pending, 0 during queue) - tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(tipThreshold), key) - if err := pool.AddRemote(tx); err != nil { - t.Fatalf("failed to replace original cheap %s transaction: %v", stage, err) - } - // 11. Check events match expected (3 new executable txs during pending, 0 during queue) - count = 2 - if stage == "queued" { - count = 0 - } - if err := validateEvents(events, count); err != nil { - t.Fatalf("replacement %s event firing failed: %v", stage, err) - } - } - - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } -} - -// Tests that local transactions are journaled to disk, but remote transactions -// get discarded between restarts. -func TestTransactionJournaling(t *testing.T) { testTransactionJournaling(t, false) } -func TestTransactionJournalingNoLocals(t *testing.T) { testTransactionJournaling(t, true) } - -func testTransactionJournaling(t *testing.T, nolocals bool) { - t.Parallel() - - // Create a temporary file for the journal - file, err := ioutil.TempFile("", "") - if err != nil { - t.Fatalf("failed to create temporary journal: %v", err) - } - journal := file.Name() - defer os.Remove(journal) - - // Clean up the temporary file, we only need the path for now - file.Close() - os.Remove(journal) - - // Create the original pool to inject transaction into the journal - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - config := testTxPoolConfig - config.NoLocals = nolocals - config.Journal = journal - config.Rejournal = time.Second - - pool := NewTxPool(config, params.TestChainConfig, blockchain) - - // Create two test accounts to ensure remotes expire but locals do not - local, _ := crypto.GenerateKey() - remote, _ := crypto.GenerateKey() - - testAddBalance(pool, crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) - testAddBalance(pool, crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) - - // Add three local and a remote transactions and ensure they are queued up - if err := pool.AddLocal(pricedTransaction(0, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add local transaction: %v", err) - } - if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add local transaction: %v", err) - } - if err := pool.AddLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil { - t.Fatalf("failed to add local transaction: %v", err) - } - if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), remote)); err != nil { - t.Fatalf("failed to add remote transaction: %v", err) - } - pending, queued := pool.Stats() - if pending != 4 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4) - } - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive - pool.Stop() - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) - blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} - - pool = NewTxPool(config, params.TestChainConfig, blockchain) - - pending, queued = pool.Stats() - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - if nolocals { - if pending != 0 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) - } - } else { - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Bump the nonce temporarily and ensure the newly invalidated transaction is removed - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2) - <-pool.requestReset(nil, nil) - time.Sleep(2 * config.Rejournal) - pool.Stop() - - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) - blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} - pool = NewTxPool(config, params.TestChainConfig, blockchain) - - pending, queued = pool.Stats() - if pending != 0 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) - } - if nolocals { - if queued != 0 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) - } - } else { - if queued != 1 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) - } - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - pool.Stop() -} - -// TestTransactionStatusCheck tests that the pool can correctly retrieve the -// pending status of individual transactions. -func TestTransactionStatusCheck(t *testing.T) { - t.Parallel() - - // Create the pool to test the status retrievals with - statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} - - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) - defer pool.Stop() - - // Create the test accounts to check various transaction statuses with - keys := make([]*ecdsa.PrivateKey, 3) - for i := 0; i < len(keys); i++ { - keys[i], _ = crypto.GenerateKey() - testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) - } - // Generate and queue a batch of transactions, both pending and queued - txs := types.Transactions{} - - txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) // Pending only - txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[1])) // Pending and queued - txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[1])) - txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2])) // Queued only - - // Import the transaction and ensure they are correctly added - pool.AddRemotesSync(txs) - - pending, queued := pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Retrieve the status of each transaction and validate them - hashes := make([]common.Hash, len(txs)) - for i, tx := range txs { - hashes[i] = tx.Hash() - } - hashes = append(hashes, common.Hash{}) - - statuses := pool.Status(hashes) - expect := []TxStatus{TxStatusPending, TxStatusPending, TxStatusQueued, TxStatusQueued, TxStatusUnknown} - - for i := 0; i < len(statuses); i++ { - if statuses[i] != expect[i] { - t.Errorf("transaction %d: status mismatch: have %v, want %v", i, statuses[i], expect[i]) - } - } -} - -// Test the transaction slots consumption is computed correctly -func TestTransactionSlotCount(t *testing.T) { - t.Parallel() - - key, _ := crypto.GenerateKey() - - // Check that an empty transaction consumes a single slot - smallTx := pricedDataTransaction(0, 0, big.NewInt(0), key, 0) - if slots := numSlots(smallTx); slots != 1 { - t.Fatalf("small transactions slot count mismatch: have %d want %d", slots, 1) - } - // Check that a large transaction consumes the correct number of slots - bigTx := pricedDataTransaction(0, 0, big.NewInt(0), key, uint64(10*txSlotSize)) - if slots := numSlots(bigTx); slots != 11 { - t.Fatalf("big transactions slot count mismatch: have %d want %d", slots, 11) - } -} - -// Benchmarks the speed of validating the contents of the pending queue of the -// transaction pool. -func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) } -func BenchmarkPendingDemotion1000(b *testing.B) { benchmarkPendingDemotion(b, 1000) } -func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 10000) } - -func benchmarkPendingDemotion(b *testing.B, size int) { - // Add a batch of transactions to a pool one by one - pool, key := setupTxPool() - defer pool.Stop() - - account := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, account, big.NewInt(1000000)) - - for i := 0; i < size; i++ { - tx := transaction(uint64(i), 100000, key) - pool.promoteTx(account, tx.Hash(), tx) - } - // Benchmark the speed of pool validation - b.ResetTimer() - for i := 0; i < b.N; i++ { - pool.demoteUnexecutables() - } -} - -// Benchmarks the speed of scheduling the contents of the future queue of the -// transaction pool. -func BenchmarkFuturePromotion100(b *testing.B) { benchmarkFuturePromotion(b, 100) } -func BenchmarkFuturePromotion1000(b *testing.B) { benchmarkFuturePromotion(b, 1000) } -func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 10000) } - -func benchmarkFuturePromotion(b *testing.B, size int) { - // Add a batch of transactions to a pool one by one - pool, key := setupTxPool() - defer pool.Stop() - - account := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, account, big.NewInt(1000000)) - - for i := 0; i < size; i++ { - tx := transaction(uint64(1+i), 100000, key) - pool.enqueueTx(tx.Hash(), tx, false, true) - } - // Benchmark the speed of pool validation - b.ResetTimer() - for i := 0; i < b.N; i++ { - pool.promoteExecutables(nil) - } -} - -// Benchmarks the speed of batched transaction insertion. -func BenchmarkPoolBatchInsert100(b *testing.B) { benchmarkPoolBatchInsert(b, 100, false) } -func BenchmarkPoolBatchInsert1000(b *testing.B) { benchmarkPoolBatchInsert(b, 1000, false) } -func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000, false) } - -func BenchmarkPoolBatchLocalInsert100(b *testing.B) { benchmarkPoolBatchInsert(b, 100, true) } -func BenchmarkPoolBatchLocalInsert1000(b *testing.B) { benchmarkPoolBatchInsert(b, 1000, true) } -func BenchmarkPoolBatchLocalInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000, true) } - -func benchmarkPoolBatchInsert(b *testing.B, size int, local bool) { - // Generate a batch of transactions to enqueue into the pool - pool, key := setupTxPool() - defer pool.Stop() - - account := crypto.PubkeyToAddress(key.PublicKey) - testAddBalance(pool, account, big.NewInt(1000000)) - - batches := make([]types.Transactions, b.N) - for i := 0; i < b.N; i++ { - batches[i] = make(types.Transactions, size) - for j := 0; j < size; j++ { - batches[i][j] = transaction(uint64(size*i+j), 100000, key) - } - } - // Benchmark importing the transactions into the queue - b.ResetTimer() - for _, batch := range batches { - if local { - pool.AddLocals(batch) - } else { - pool.AddRemotes(batch) - } - } -} - -func BenchmarkInsertRemoteWithAllLocals(b *testing.B) { - // Allocate keys for testing - key, _ := crypto.GenerateKey() - account := crypto.PubkeyToAddress(key.PublicKey) - - remoteKey, _ := crypto.GenerateKey() - remoteAddr := crypto.PubkeyToAddress(remoteKey.PublicKey) - - locals := make([]*types.Transaction, 4096+1024) // Occupy all slots - for i := 0; i < len(locals); i++ { - locals[i] = transaction(uint64(i), 100000, key) - } - remotes := make([]*types.Transaction, 1000) - for i := 0; i < len(remotes); i++ { - remotes[i] = pricedTransaction(uint64(i), 100000, big.NewInt(2), remoteKey) // Higher gasprice - } - // Benchmark importing the transactions into the queue - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() - pool, _ := setupTxPool() - testAddBalance(pool, account, big.NewInt(100000000)) - for _, local := range locals { - pool.AddLocal(local) - } - b.StartTimer() - // Assign a high enough balance for testing - testAddBalance(pool, remoteAddr, big.NewInt(100000000)) - for i := 0; i < len(remotes); i++ { - pool.AddRemotes([]*types.Transaction{remotes[i]}) - } - pool.Stop() - } -} diff --git a/evm/go-x1/evmcore/types.go b/evm/go-x1/evmcore/types.go deleted file mode 100644 index 9ab786c..0000000 --- a/evm/go-x1/evmcore/types.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" -) - -// Validator is an interface which defines the standard for block validation. It -// is only responsible for validating block contents, as the header validation is -// done by the specific consensus engines. -type Validator interface { - // ValidateBody validates the given block's content. - ValidateBody(block *EvmBlock) error - - // ValidateState validates the given statedb and optionally the receipts and - // gas used. - ValidateState(block *EvmBlock, state *state.StateDB, receipts types.Receipts, usedGas uint64) error -} - -// Prefetcher is an interface for pre-caching transaction signatures and state. -type Prefetcher interface { - // Prefetch processes the state changes according to the Ethereum rules by running - // the transaction messages using the statedb, but any changes are discarded. The - // only goal is to pre-cache transaction signatures and state trie nodes. - Prefetch(block *EvmBlock, statedb *state.StateDB, cfg vm.Config, interrupt *uint32) -} - -// Processor is an interface for processing blocks using a given initial state. -type Processor interface { - // Process processes the state changes according to the Ethereum rules by running - // the transaction messages using the statedb and applying any rewards to both - // the processor (coinbase) and any included uncles. - Process(block *EvmBlock, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) -} diff --git a/evm/go-x1/flags/helpers.go b/evm/go-x1/flags/helpers.go deleted file mode 100644 index 3310937..0000000 --- a/evm/go-x1/flags/helpers.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -package flags - -import ( - "os" - "path/filepath" - - "github.com/ethereum/go-ethereum/params" - cli "gopkg.in/urfave/cli.v1" -) - -var ( - CommandHelpTemplate = `{{.cmd.Name}}{{if .cmd.Subcommands}} command{{end}}{{if .cmd.Flags}} [command options]{{end}} {{.cmd.ArgsUsage}} -{{if .cmd.Description}}{{.cmd.Description}} -{{end}}{{if .cmd.Subcommands}} -SUBCOMMANDS: - {{range .cmd.Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{end}}{{if .categorizedFlags}} -{{range $idx, $categorized := .categorizedFlags}}{{$categorized.Name}} OPTIONS: -{{range $categorized.Flags}}{{"\t"}}{{.}} -{{end}} -{{end}}{{end}}` - - // AppHelpTemplate is the test template for the default, global app help topic. - AppHelpTemplate = `NAME: - {{.App.Name}} - {{.App.Usage}} - - Copyright 2019-2021 The go-opera Authors - -USAGE: - {{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}} - {{if .App.Version}} -VERSION: - {{.App.Version}} - {{end}}{{if len .App.Authors}} -AUTHOR(S): - {{range .App.Authors}}{{ . }}{{end}} - {{end}}{{if .App.Commands}} -COMMANDS: - {{range .App.Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} - {{end}}{{end}}{{if .FlagGroups}} -{{range .FlagGroups}}{{.Name}} OPTIONS: - {{range .Flags}}{{.}} - {{end}} -{{end}}{{end}}{{if .App.Copyright }} -COPYRIGHT: - {{.App.Copyright}} - {{end}} -` -) - -// HelpData is a one shot struct to pass to the usage template -type HelpData struct { - App interface{} - FlagGroups []FlagGroup -} - -// FlagGroup is a collection of flags belonging to a single topic. -type FlagGroup struct { - Name string - Flags []cli.Flag -} - -// byCategory sorts an array of FlagGroup by Name in the order -// defined in AppHelpFlagGroups. -type ByCategory []FlagGroup - -func (a ByCategory) Len() int { return len(a) } -func (a ByCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByCategory) Less(i, j int) bool { - iCat, jCat := a[i].Name, a[j].Name - iIdx, jIdx := len(a), len(a) // ensure non categorized flags come last - - for i, group := range a { - if iCat == group.Name { - iIdx = i - } - if jCat == group.Name { - jIdx = i - } - } - - return iIdx < jIdx -} - -func FlagCategory(flag cli.Flag, flagGroups []FlagGroup) string { - for _, category := range flagGroups { - for _, flg := range category.Flags { - if flg.GetName() == flag.GetName() { - return category.Name - } - } - } - return "MISC" -} - -// NewApp creates an app with sane defaults. -func NewApp(gitCommit, gitDate, usage string) *cli.App { - app := cli.NewApp() - app.Name = filepath.Base(os.Args[0]) - app.Author = "" - app.Email = "" - app.Version = params.VersionWithCommit(gitCommit, gitDate) - app.Usage = usage - return app -} diff --git a/evm/go-x1/ftmclient/dag_api.go b/evm/go-x1/ftmclient/dag_api.go deleted file mode 100644 index 470a671..0000000 --- a/evm/go-x1/ftmclient/dag_api.go +++ /dev/null @@ -1,91 +0,0 @@ -package ftmclient - -import ( - "context" - "math/big" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - - "github.com/Fantom-foundation/go-opera/inter" -) - -// GetEvent returns Lachesis event by hash or short ID. -func (ec *Client) GetEvent(ctx context.Context, h hash.Event) (e inter.EventI, err error) { - var raw map[string]interface{} - err = ec.c.CallContext(ctx, &raw, "dag_getEvent", h.Hex()) - if err != nil { - return - } else if len(raw) == 0 { - err = ethereum.NotFound - return - } - - e = inter.RPCUnmarshalEvent(raw) - return -} - -// GetEvent returns Lachesis event by hash or short ID. -func (ec *Client) GetEventPayload(ctx context.Context, h hash.Event, inclTx bool) (e inter.EventI, txs []common.Hash, err error) { - var raw map[string]interface{} - err = ec.c.CallContext(ctx, &raw, "dag_getEventPayload", h.Hex(), inclTx) - if err != nil { - return - } else if len(raw) == 0 { - err = ethereum.NotFound - return - } - - e = inter.RPCUnmarshalEvent(raw) - - if inclTx { - vv := raw["transactions"].([]interface{}) - txs = make([]common.Hash, len(vv)) - for i, v := range vv { - txs[i] = common.HexToHash(v.(string)) - } - } - - return -} - -// GetHeads returns IDs of all the epoch events with no descendants. -// * When epoch is -2 the heads for latest epoch are returned. -// * When epoch is -1 the heads for latest sealed epoch are returned. -func (ec *Client) GetHeads(ctx context.Context, epoch *big.Int) (hash.Events, error) { - var raw []interface{} - err := ec.c.CallContext(ctx, &raw, "dag_getHeads", toBlockNumArg(epoch)) - if err != nil { - return nil, err - } - - return inter.HexToEventIDs(raw), nil -} - -// GetEpochStats returns epoch statistics. -// * When epoch is -2 the statistics for latest epoch is returned. -// * When epoch is -1 the statistics for latest sealed epoch is returned. -func (ec *Client) GetEpochStats(ctx context.Context, epoch *big.Int) (map[string]interface{}, error) { - var raw map[string]interface{} - err := ec.c.CallContext(ctx, &raw, "dag_getEpochStats", toBlockNumArg(epoch)) - if err != nil { - return nil, err - } else if len(raw) == 0 { - return nil, ethereum.NotFound - } - - return raw, nil -} - -func toBlockNumArg(number *big.Int) string { - if number == nil { - return "latest" - } - pending := big.NewInt(-1) - if number.Cmp(pending) == 0 { - return "pending" - } - return hexutil.EncodeBig(number) -} diff --git a/evm/go-x1/ftmclient/ethclient.go b/evm/go-x1/ftmclient/ethclient.go deleted file mode 100644 index cdb72c3..0000000 --- a/evm/go-x1/ftmclient/ethclient.go +++ /dev/null @@ -1,35 +0,0 @@ -package ftmclient - -import ( - "context" - - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/rpc" -) - -// Client extends Ethereum API client with typed wrappers for the FTM API. -type Client struct { - ethclient.Client - c *rpc.Client -} - -// Dial connects a client to the given URL. -func Dial(rawurl string) (*Client, error) { - return DialContext(context.Background(), rawurl) -} - -func DialContext(ctx context.Context, rawurl string) (*Client, error) { - c, err := rpc.DialContext(ctx, rawurl) - if err != nil { - return nil, err - } - return NewClient(c), nil -} - -// NewClient creates a client that uses the given RPC client. -func NewClient(c *rpc.Client) *Client { - return &Client{ - Client: *ethclient.NewClient(c), - c: c, - } -} diff --git a/evm/go-x1/go.mod b/evm/go-x1/go.mod deleted file mode 100644 index 1fa409b..0000000 --- a/evm/go-x1/go.mod +++ /dev/null @@ -1,112 +0,0 @@ -module github.com/Fantom-foundation/go-opera - -go 1.17 - -require ( - github.com/Fantom-foundation/lachesis-base v0.0.0-20230817040848-1326ba9aa59b - github.com/allegro/bigcache v1.2.1 // indirect - github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40 // indirect - github.com/cespare/cp v1.1.1 - github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect - github.com/davecgh/go-spew v1.1.1 - github.com/deckarep/golang-set v1.7.1 - github.com/docker/docker v1.13.1 - github.com/dvyukov/go-fuzz v0.0.0-20201127111758-49e582c6c23d - github.com/ethereum/go-ethereum v1.10.8 - github.com/evalphobia/logrus_sentry v0.8.2 - github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 - github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect - github.com/getsentry/raven-go v0.2.0 // indirect - github.com/golang/mock v1.6.0 - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d - github.com/holiman/bloomfilter/v2 v2.0.3 - github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect - github.com/mattn/go-colorable v0.1.8 - github.com/mattn/go-isatty v0.0.12 - github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 - github.com/opentracing/opentracing-go v1.1.0 - github.com/pkg/errors v0.9.1 - github.com/prometheus/tsdb v0.10.0 // indirect - github.com/rjeczalik/notify v0.9.2 // indirect - github.com/sirupsen/logrus v1.6.0 - github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 - github.com/stretchr/testify v1.8.1 - github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 - github.com/tyler-smith/go-bip39 v1.0.2 - github.com/uber/jaeger-client-go v2.20.1+incompatible - github.com/uber/jaeger-lib v2.2.0+incompatible - go.uber.org/atomic v1.5.1 // indirect - golang.org/x/crypto v0.7.0 - golang.org/x/sys v0.6.0 - golang.org/x/tools v0.6.0 // indirect - gopkg.in/urfave/cli.v1 v1.20.0 -) - -require ( - github.com/DataDog/zstd v1.4.5 // indirect - github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect - github.com/VictoriaMetrics/fastcache v1.6.0 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/btcsuite/btcd v0.20.1-beta // indirect - github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/cockroachdb/errors v1.8.1 // indirect - github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect - github.com/cockroachdb/pebble v0.0.0-20221111210721-1bda21f14fc2 // indirect - github.com/cockroachdb/redact v1.0.8 // indirect - github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 // indirect - github.com/deepmap/oapi-codegen v1.8.2 // indirect - github.com/dlclark/regexp2 v1.2.0 // indirect - github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 // indirect - github.com/edsrzf/mmap-go v1.0.0 // indirect - github.com/emirpasic/gods v1.12.0 // indirect - github.com/fatih/color v1.7.0 // indirect - github.com/go-ole/go-ole v1.2.1 // indirect - github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect - github.com/go-stack/stack v1.8.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/uuid v1.1.5 // indirect - github.com/gorilla/websocket v1.4.2 // indirect - github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 // indirect - github.com/holiman/uint256 v1.2.0 // indirect - github.com/huin/goupnp v1.0.2 // indirect - github.com/influxdata/influxdb v1.8.3 // indirect - github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect - github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect - github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 // indirect - github.com/klauspost/compress v1.11.13 // indirect - github.com/kr/pretty v0.2.1 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect - github.com/naoina/go-stringutil v0.1.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.12.0 // indirect - github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect - github.com/rs/cors v1.7.0 // indirect - github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect - github.com/tklauser/go-sysconf v0.3.5 // indirect - github.com/tklauser/numcpus v0.2.2 // indirect - golang.org/x/exp v0.0.0-20200513190911-00229845015e // indirect - golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/text v0.8.0 // indirect - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect - google.golang.org/protobuf v1.27.1 // indirect - gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect - gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) - -replace github.com/ethereum/go-ethereum => github.com/Fantom-foundation/go-ethereum v1.10.8-ftm-rc12 - -replace github.com/dvyukov/go-fuzz => github.com/guzenok/go-fuzz v0.0.0-20210201043429-a8e90a2a4f88 diff --git a/evm/go-x1/go.sum b/evm/go-x1/go.sum deleted file mode 100644 index d81a848..0000000 --- a/evm/go-x1/go.sum +++ /dev/null @@ -1,1078 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/Fantom-foundation/go-ethereum v1.10.8-ftm-rc12 h1:SyXrKgZNRBIQN1XZXOH1WZZoPft2qm0jC7pZC9nRCw4= -github.com/Fantom-foundation/go-ethereum v1.10.8-ftm-rc12/go.mod h1:IeQDjWCNBj/QiWIPosfF6/kRC6pHPNs7W7LfBzjj+P4= -github.com/Fantom-foundation/lachesis-base v0.0.0-20230817040848-1326ba9aa59b h1:/9+Cau3cWaKy9fQk/NWq3RJKrwEjgrhME6ACy4RjLns= -github.com/Fantom-foundation/lachesis-base v0.0.0-20230817040848-1326ba9aa59b/go.mod h1:Ogv5etzSmM2rQ4eN3OfmyitwWaaPjd4EIDiW/NAbYGk= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/JekaMas/go-mutesting v1.1.2/go.mod h1:dmuQcwN24lbeoiakrWYmmPQ/YcLYSRADixUrGdcCkxI= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= -github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= -github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= -github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= -github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= -github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= -github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= -github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= -github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= -github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5 h1:BjkPE3785EwPhhyuFkbINB+2a1xATwk8SNDWnJiD41g= -github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5/go.mod h1:jtAfVaU/2cu1+wdSRPWE2c1N2qeAA3K4RH9pYgqwets= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40 h1:xvUo53O5MRZhVMJAxWCJcS5HHrqAiAG9SJ1LpMu6aAI= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= -github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= -github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= -github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/pebble v0.0.0-20221111210721-1bda21f14fc2 h1:AOMHSawcy6IMi72k2UUb0AJceuQ/u224Z27laEvJxXw= -github.com/cockroachdb/pebble v0.0.0-20221111210721-1bda21f14fc2/go.mod h1:qf9bLis2yy1XyNYD01wvIHPabuC1STzQsvGibYVsom4= -github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= -github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= -github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= -github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= -github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= -github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= -github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= -github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk= -github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= -github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 h1:Y9vTBSsV4hSwPSj4bacAU/eSnV3dAxVpepaghAdhGoQ= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/evalphobia/logrus_sentry v0.8.2 h1:dotxHq+YLZsT1Bb45bB5UQbfCh3gM/nFFetyN46VoDQ= -github.com/evalphobia/logrus_sentry v0.8.2/go.mod h1:pKcp+vriitUqu9KiWj/VRFbRfFNUwz95/UkgG8a6MNc= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= -github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible h1:0b/xya7BKGhXuqFESKM4oIiRo9WOt2ebz7KxfreD6ug= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I= -github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 h1:sezaKhEfPFg8W0Enm61B9Gs911H8iesGY5R8NDPtd1M= -github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/guzenok/go-fuzz v0.0.0-20210201043429-a8e90a2a4f88 h1:91ADdeyQRa7l7/a8L+gbtXR5DHTplkAYkhxpHNyR9uo= -github.com/guzenok/go-fuzz v0.0.0-20210201043429-a8e90a2a4f88/go.mod h1:Q5On640X2Z0YzKOijx9GVhUu/kvHnk9aKoWGMlRDMtc= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= -github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= -github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI= -github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8= -github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= -github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= -github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= -github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= -github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= -github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsDSy7TDxedi9gyBkMvAirat/oRcL0lFdJBf6tdM= -github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= -github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= -github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= -github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA= -github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 h1:ZHuwnjpP8LsVsUYqTqeVAI+GfDfJ6UNPrExZF+vX/DQ= -github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= -github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= -github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= -github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= -github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= -github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= -github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= -github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= -github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= -github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= -github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 h1:ju5UTwk5Odtm4trrY+4Ca4RMj5OyXbmVeDAVad2T0Jw= -github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 h1:xQdMZ1WLrgkkvOZ/LDQxjVxMLdby7osSh4ZEVa5sIjs= -github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= -github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= -github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/uber/jaeger-client-go v2.20.1+incompatible h1:HgqpYBng0n7tLJIlyT4kPCIv5XgCsF+kai1NnnrJzEU= -github.com/uber/jaeger-client-go v2.20.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw= -github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zimmski/osutil v0.0.0-20190128123334-0d0b3ca231ac/go.mod h1:wJ9WGevuM/rw8aB2pQPFMUgXZWeaouI0ueFamR0DUPE= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM= -go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20200513190911-00229845015e h1:rMqLP+9XLy+LdbCXHjJHAmTfXCr93W7oruWA6Hq1Alc= -golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/evm/go-x1/gossip/api.go b/evm/go-x1/gossip/api.go deleted file mode 100644 index 5d9bc6b..0000000 --- a/evm/go-x1/gossip/api.go +++ /dev/null @@ -1,37 +0,0 @@ -package gossip - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -// PublicEthereumAPI provides an API to access Ethereum-like information. -// It is a github.com/ethereum/go-ethereum/eth simulation for console. -type PublicEthereumAPI struct { - s *Service -} - -// NewPublicEthereumAPI creates a new Ethereum protocol API for gossip. -func NewPublicEthereumAPI(s *Service) *PublicEthereumAPI { - return &PublicEthereumAPI{s} -} - -// Etherbase returns the zero address for web3 compatibility -func (api *PublicEthereumAPI) Etherbase() (common.Address, error) { - return common.Address{}, nil -} - -// Coinbase returns the zero address for web3 compatibility -func (api *PublicEthereumAPI) Coinbase() (common.Address, error) { - return common.Address{}, nil -} - -// Hashrate returns the zero POW hashrate for web3 compatibility -func (api *PublicEthereumAPI) Hashrate() hexutil.Uint64 { - return hexutil.Uint64(0) -} - -// ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config. -func (api *PublicEthereumAPI) ChainId() hexutil.Uint64 { - return hexutil.Uint64(api.s.store.GetRules().NetworkID) -} diff --git a/evm/go-x1/gossip/apply_genesis.go b/evm/go-x1/gossip/apply_genesis.go deleted file mode 100644 index c34ba70..0000000 --- a/evm/go-x1/gossip/apply_genesis.go +++ /dev/null @@ -1,94 +0,0 @@ -package gossip - -import ( - "errors" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/kvdb/batched" - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/utils/dbutil/autocompact" -) - -// ApplyGenesis writes initial state. -func (s *Store) ApplyGenesis(g genesis.Genesis) (genesisHash hash.Hash, err error) { - // use batching wrapper for hot tables - unwrap := s.WrapTablesAsBatched() - defer unwrap() - - // write epochs - var topEr *ier.LlrIdxFullEpochRecord - g.Epochs.ForEach(func(er ier.LlrIdxFullEpochRecord) bool { - if er.EpochState.Rules.NetworkID != g.NetworkID || er.EpochState.Rules.Name != g.NetworkName { - err = errors.New("network ID/name mismatch") - return false - } - if topEr == nil { - topEr = &er - } - s.WriteFullEpochRecord(er) - return true - }) - if err != nil { - return genesisHash, err - } - if topEr == nil { - return genesisHash, errors.New("no ERs in genesis") - } - var prevEs *iblockproc.EpochState - s.ForEachHistoryBlockEpochState(func(bs iblockproc.BlockState, es iblockproc.EpochState) bool { - s.WriteUpgradeHeight(bs, es, prevEs) - prevEs = &es - return true - }) - s.SetBlockEpochState(topEr.BlockState, topEr.EpochState) - s.FlushBlockEpochState() - - // write blocks - g.Blocks.ForEach(func(br ibr.LlrIdxFullBlockRecord) bool { - s.WriteFullBlockRecord(br) - return true - }) - - // write EVM items - err = s.evm.ApplyGenesis(g) - if err != nil { - return genesisHash, err - } - - // write LLR state - s.setLlrState(LlrState{ - LowestEpochToDecide: topEr.Idx + 1, - LowestEpochToFill: topEr.Idx + 1, - LowestBlockToDecide: topEr.BlockState.LastBlock.Idx + 1, - LowestBlockToFill: topEr.BlockState.LastBlock.Idx + 1, - }) - s.FlushLlrState() - - s.SetGenesisID(g.GenesisID) - s.SetGenesisBlockIndex(topEr.BlockState.LastBlock.Idx) - - return genesisHash, err -} - -func (s *Store) WrapTablesAsBatched() (unwrap func()) { - origTables := s.table - - batchedBlocks := batched.Wrap(autocompact.Wrap2M(s.table.Blocks, opt.GiB, 16*opt.GiB, false, "blocks")) - s.table.Blocks = batchedBlocks - - batchedBlockHashes := batched.Wrap(s.table.BlockHashes) - s.table.BlockHashes = batchedBlockHashes - - unwrapEVM := s.evm.WrapTablesAsBatched() - return func() { - unwrapEVM() - _ = batchedBlocks.Flush() - _ = batchedBlockHashes.Flush() - s.table = origTables - } -} diff --git a/evm/go-x1/gossip/basiccheck_test.go b/evm/go-x1/gossip/basiccheck_test.go deleted file mode 100644 index d0485b3..0000000 --- a/evm/go-x1/gossip/basiccheck_test.go +++ /dev/null @@ -1,905 +0,0 @@ -package gossip - -import ( - "bytes" - "math" - "math/big" - "testing" - - lbasiccheck "github.com/Fantom-foundation/lachesis-base/eventcheck/basiccheck" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/suite" - - "github.com/Fantom-foundation/go-opera/eventcheck/basiccheck" - "github.com/Fantom-foundation/go-opera/inter" -) - -type LLRBasicCheckTestSuite struct { - suite.Suite - - env *testEnv - me *inter.MutableEventPayload - startEpoch idx.Epoch -} - -func (s *LLRBasicCheckTestSuite) SetupSuite() { - s.T().Log("setting up test suite") - - const ( - validatorsNum = 10 - startEpoch = 1 - ) - - env := newTestEnv(startEpoch, validatorsNum) - - em := env.emitters[0] - e, err := em.EmitEvent() - s.Require().NoError(err) - s.Require().NotNil(e) - - s.env = env - s.me = mutableEventPayloadFromImmutable(e) - s.startEpoch = idx.Epoch(startEpoch) -} - -func (s *LLRBasicCheckTestSuite) TearDownSuite() { - s.T().Log("tearing down test suite") - s.env.Close() -} - -func (s *LLRBasicCheckTestSuite) TestBasicCheckValidate() { - - testCases := []struct { - name string - pretest func() - errExp error - }{ - - { - "ErrWrongNetForkID", - func() { - s.me.SetNetForkID(1) - }, - basiccheck.ErrWrongNetForkID, - }, - - { - "Validate checkLimits ErrHugeValue", - func() { - s.me.SetEpoch(math.MaxInt32 - 1) - }, - lbasiccheck.ErrHugeValue, - }, - { - "Validate checkInited checkInited ErrNotInited ", - func() { - s.me.SetSeq(0) - }, - lbasiccheck.ErrNotInited, - }, - { - "Validate checkInited ErrNoParents", - func() { - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - s.me.SetSeq(idx.Event(2)) - parents := hash.Events{} - s.me.SetParents(parents) - }, - lbasiccheck.ErrNoParents, - }, - { - "Validate ErrHugeValue-1", - func() { - s.me.SetSeq(idx.Event(1)) - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - s.me.SetGasPowerUsed(math.MaxInt64 - 1) - }, - lbasiccheck.ErrHugeValue, - }, - { - "Validate ErrHugeValue-2", - func() { - s.me.SetSeq(idx.Event(1)) - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - s.me.SetGasPowerLeft(inter.GasPowerLeft{Gas: [2]uint64{math.MaxInt64 - 1, math.MaxInt64}}) - }, - lbasiccheck.ErrHugeValue, - }, - { - "Validate ErrZeroTime-1", - func() { - s.me.SetSeq(idx.Event(1)) - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - s.me.SetCreationTime(0) - }, - basiccheck.ErrZeroTime, - }, - { - "Validate ErrZeroTime-2", - func() { - s.me.SetSeq(idx.Event(1)) - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - s.me.SetMedianTime(0) - }, - basiccheck.ErrZeroTime, - }, - { - "Validate checkTxs validateTx ErrNegativeValue-1", - func() { - s.me.SetSeq(idx.Event(1)) - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - h := hash.BytesToEvent(bytes.Repeat([]byte{math.MaxUint8}, 32)) - tx1 := types.NewTx(&types.LegacyTx{ - Nonce: math.MaxUint64, - GasPrice: h.Big(), - Gas: math.MaxUint64, - To: nil, - Value: big.NewInt(-1000), - Data: []byte{}, - V: big.NewInt(0xff), - R: h.Big(), - S: h.Big(), - }) - txs := types.Transactions{} - txs = append(txs, tx1) - s.me.SetTxs(txs) - }, - basiccheck.ErrNegativeValue, - }, - { - "Validate checkTxs validateTx ErrNegativeValue-2", - func() { - s.me.SetSeq(idx.Event(1)) - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - h := hash.BytesToEvent(bytes.Repeat([]byte{math.MaxUint8}, 32)) - tx1 := types.NewTx(&types.LegacyTx{ - Nonce: math.MaxUint64, - GasPrice: big.NewInt(-1000), - Gas: math.MaxUint64, - To: nil, - Value: h.Big(), - Data: []byte{}, - V: big.NewInt(0xff), - R: h.Big(), - S: h.Big(), - }) - txs := types.Transactions{} - txs = append(txs, tx1) - s.me.SetTxs(txs) - }, - basiccheck.ErrNegativeValue, - }, - { - "Validate checkTxs validateTx ErrIntrinsicGas", - func() { - s.me.SetSeq(idx.Event(1)) - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - h := hash.BytesToEvent(bytes.Repeat([]byte{math.MaxUint8}, 32)) - tx1 := types.NewTx(&types.LegacyTx{ - Nonce: math.MaxUint64, - GasPrice: h.Big(), - Gas: 0, - To: nil, - Value: h.Big(), - Data: []byte{}, - V: big.NewInt(0xff), - R: h.Big(), - S: h.Big(), - }) - txs := types.Transactions{} - txs = append(txs, tx1) - s.me.SetTxs(txs) - }, - basiccheck.ErrIntrinsicGas, - }, - - { - "Validate checkTxs validateTx ErrTipAboveFeeCap", - func() { - s.me.SetSeq(idx.Event(1)) - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - h := hash.BytesToEvent(bytes.Repeat([]byte{math.MaxUint8}, 32)) - - tx1 := types.NewTx(&types.DynamicFeeTx{ - Nonce: math.MaxUint64, - To: nil, - Data: []byte{}, - Gas: math.MaxUint64, - Value: h.Big(), - ChainID: new(big.Int), - GasTipCap: big.NewInt(1000), - GasFeeCap: new(big.Int), - V: big.NewInt(0xff), - R: h.Big(), - S: h.Big(), - }) - - txs := types.Transactions{} - txs = append(txs, tx1) - s.me.SetTxs(txs) - }, - basiccheck.ErrTipAboveFeeCap, - }, - { - "Validate returns nil", - func() { - s.me.SetSeq(idx.Event(1)) - s.me.SetEpoch(idx.Epoch(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - - h := hash.BytesToEvent(bytes.Repeat([]byte{math.MaxUint8}, 32)) - - tx1 := types.NewTx(&types.DynamicFeeTx{ - Nonce: math.MaxUint64, - To: nil, - Data: []byte{}, - Gas: math.MaxUint64, - Value: h.Big(), - ChainID: new(big.Int), - GasTipCap: new(big.Int), - GasFeeCap: big.NewInt(1000), - V: big.NewInt(0xff), - R: h.Big(), - S: h.Big(), - }) - - txs := types.Transactions{} - txs = append(txs, tx1) - s.me.SetTxs(txs) - }, - nil, - }, - } - - for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { - s.SetupSuite() - tc.pretest() - - err := s.env.checkers.Basiccheck.Validate(s.me) - - if tc.errExp != nil { - s.Require().Error(err) - s.Require().EqualError(err, tc.errExp.Error()) - } else { - s.Require().NoError(err) - } - }) - } -} - -func (s *LLRBasicCheckTestSuite) TestBasicCheckValidateEV() { - - var ev inter.LlrSignedEpochVote - - testCases := []struct { - name string - errExp error - pretest func() - }{ - { - "validateEV returns nil", - nil, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEventLocator ErrWrongNetForkID", - basiccheck.ErrWrongNetForkID, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetNetForkID(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEventLocator ErrHugeValue-1 e.Seq >= math.MaxInt32-1 ", - lbasiccheck.ErrHugeValue, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetSeq(idx.Event(math.MaxInt32 - 1)) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEventLocator ErrHugeValue-2 e.Epoch >= math.MaxInt32-1", - lbasiccheck.ErrHugeValue, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(math.MaxInt32 - 1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEventLocator ErrHugeValue-3 e.Lamport >= math.MaxInt32-1", - lbasiccheck.ErrHugeValue, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetLamport(idx.Lamport(math.MaxInt32 - 1)) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(math.MaxInt32 - 1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEV ErrFutureEVEpoch", - basiccheck.FutureEVEpoch, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(s.startEpoch) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEV MalformedEV-1", - basiccheck.MalformedEV, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: 0, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(s.startEpoch) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEV MalformedEV-2", - basiccheck.MalformedEV, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch, - Vote: hash.Zero, - }, - } - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(s.startEpoch) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEV ErrHugeValue", - lbasiccheck.ErrHugeValue, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: math.MaxInt32 - 1, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(math.MaxInt32 - 1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEV EmptyEV", - basiccheck.EmptyEV, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: 0, - Vote: hash.Zero, - }, - } - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - } - - for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { - s.SetupSuite() - tc.pretest() - - err := s.env.checkers.Basiccheck.ValidateEV(ev) - - if tc.errExp != nil { - s.Require().Error(err) - s.Require().EqualError(err, tc.errExp.Error()) - } else { - s.Require().NoError(err) - } - }) - } - -} - -func (s *LLRBasicCheckTestSuite) TestBasicCheckValidateBV() { - var bv inter.LlrSignedBlockVotes - - testCases := []struct { - name string - errExp error - pretest func() - }{ - { - "validateBV returns nil", - nil, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBV ErrWrongNetForkID", - basiccheck.ErrWrongNetForkID, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - s.me.SetNetForkID(1) - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBVs ErrHugeValue e.Seq >= math.MaxInt32-1", - lbasiccheck.ErrHugeValue, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetSeq(idx.Event(math.MaxInt32 - 1)) - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBVs ErrHugeValue e.Epoch >= math.MaxInt32-1", - lbasiccheck.ErrHugeValue, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetEpoch(idx.Epoch(math.MaxInt32 - 1)) - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBVs ErrHugeValue e.Lamport >= math.MaxInt32-1", - lbasiccheck.ErrHugeValue, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetLamport(idx.Lamport(math.MaxInt32 - 1)) - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBVs FutureBVsEpoc", - basiccheck.FutureBVsEpoch, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch + 1, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBVs ErrHugeValue-1", - basiccheck.FutureBVsEpoch, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: math.MaxInt64 / 2, - Epoch: s.startEpoch + 1, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBVs ErrHugeValue-2", - basiccheck.FutureBVsEpoch, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: math.MaxInt32 - 1, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBVs TooManyBVs", - basiccheck.TooManyBVs, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - for j := 0; j < basiccheck.MaxBlockVotesPerEvent+1; j++ { - bv.Val.Votes = append(bv.Val.Votes, hash.HexToHash("0x01")) - } - - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBVs MalformedBVs", - basiccheck.MalformedBVs, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: 0, - Votes: []hash.Hash{}, - }, - } - - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "validateBVs EmptyBVs", - basiccheck.EmptyBVs, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 0, - Epoch: 0, - Votes: []hash.Hash{}, - }, - } - - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetBlockVotes(bv.Val) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - } - - for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { - s.SetupSuite() - tc.pretest() - - err := s.env.checkers.Basiccheck.ValidateBVs(bv) - - if tc.errExp != nil { - s.Require().Error(err) - s.Require().EqualError(err, tc.errExp.Error()) - } else { - s.Require().NoError(err) - } - }) - } - -} - -func TestBasicCheckIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(LLRBasicCheckTestSuite)) -} diff --git a/evm/go-x1/gossip/blockproc/drivermodule/driver_txs.go b/evm/go-x1/gossip/blockproc/drivermodule/driver_txs.go deleted file mode 100644 index 66380f1..0000000 --- a/evm/go-x1/gossip/blockproc/drivermodule/driver_txs.go +++ /dev/null @@ -1,241 +0,0 @@ -package drivermodule - -import ( - "io" - "math" - "math/big" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - - "github.com/Fantom-foundation/go-opera/gossip/blockproc" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/drivertype" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver/drivercall" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver/driverpos" -) - -const ( - maxAdvanceEpochs = 1 << 16 -) - -type DriverTxListenerModule struct{} - -func NewDriverTxListenerModule() *DriverTxListenerModule { - return &DriverTxListenerModule{} -} - -func (m *DriverTxListenerModule) Start(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, statedb *state.StateDB) blockproc.TxListener { - return &DriverTxListener{ - block: block, - es: es, - bs: bs, - statedb: statedb, - } -} - -type DriverTxListener struct { - block iblockproc.BlockCtx - es iblockproc.EpochState - bs iblockproc.BlockState - statedb *state.StateDB -} - -type DriverTxTransactor struct{} - -type DriverTxPreTransactor struct{} - -func NewDriverTxTransactor() *DriverTxTransactor { - return &DriverTxTransactor{} -} - -func NewDriverTxPreTransactor() *DriverTxPreTransactor { - return &DriverTxPreTransactor{} -} - -func InternalTxBuilder(statedb *state.StateDB) func(calldata []byte, addr common.Address) *types.Transaction { - nonce := uint64(math.MaxUint64) - return func(calldata []byte, addr common.Address) *types.Transaction { - if nonce == math.MaxUint64 { - nonce = statedb.GetNonce(common.Address{}) - } - tx := types.NewTransaction(nonce, addr, common.Big0, 1e10, common.Big0, calldata) - nonce++ - return tx - } -} - -func maxBlockIdx(a, b idx.Block) idx.Block { - if a > b { - return a - } - return b -} - -func (p *DriverTxPreTransactor) PopInternalTxs(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, sealing bool, statedb *state.StateDB) types.Transactions { - buildTx := InternalTxBuilder(statedb) - internalTxs := make(types.Transactions, 0, 8) - - // write cheaters - for _, validatorID := range bs.EpochCheaters[bs.CheatersWritten:] { - calldata := drivercall.DeactivateValidator(validatorID, drivertype.DoublesignBit) - internalTxs = append(internalTxs, buildTx(calldata, driver.ContractAddress)) - } - - // push data into Driver before epoch sealing - if sealing { - metrics := make([]drivercall.ValidatorEpochMetric, es.Validators.Len()) - for oldValIdx := idx.Validator(0); oldValIdx < es.Validators.Len(); oldValIdx++ { - info := bs.ValidatorStates[oldValIdx] - // forgive downtime if below BlockMissedSlack - missed := opera.BlocksMissed{ - BlocksNum: maxBlockIdx(block.Idx, info.LastBlock) - info.LastBlock, - Period: inter.MaxTimestamp(block.Time, info.LastOnlineTime) - info.LastOnlineTime, - } - uptime := info.Uptime - if missed.BlocksNum <= es.Rules.Economy.BlockMissedSlack { - missed = opera.BlocksMissed{} - prevOnlineTime := inter.MaxTimestamp(info.LastOnlineTime, es.EpochStart) - uptime += inter.MaxTimestamp(block.Time, prevOnlineTime) - prevOnlineTime - } - metrics[oldValIdx] = drivercall.ValidatorEpochMetric{ - Missed: missed, - Uptime: uptime, - OriginatedTxFee: info.Originated, - } - } - calldata := drivercall.SealEpoch(metrics) - internalTxs = append(internalTxs, buildTx(calldata, driver.ContractAddress)) - } - return internalTxs -} - -func (p *DriverTxTransactor) PopInternalTxs(_ iblockproc.BlockCtx, _ iblockproc.BlockState, es iblockproc.EpochState, sealing bool, statedb *state.StateDB) types.Transactions { - buildTx := InternalTxBuilder(statedb) - internalTxs := make(types.Transactions, 0, 1) - // push data into Driver after epoch sealing - if sealing { - calldata := drivercall.SealEpochValidators(es.Validators.SortedIDs()) - internalTxs = append(internalTxs, buildTx(calldata, driver.ContractAddress)) - } - return internalTxs -} - -func (p *DriverTxListener) OnNewReceipt(tx *types.Transaction, r *types.Receipt, originator idx.ValidatorID) { - if originator == 0 { - return - } - originatorIdx := p.es.Validators.GetIdx(originator) - - // track originated fee - txFee := new(big.Int).Mul(new(big.Int).SetUint64(r.GasUsed), tx.GasPrice()) - originated := p.bs.ValidatorStates[originatorIdx].Originated - originated.Add(originated, txFee) - - // track gas power refunds - notUsedGas := tx.Gas() - r.GasUsed - if notUsedGas != 0 { - p.bs.ValidatorStates[originatorIdx].DirtyGasRefund += notUsedGas - } -} - -func decodeDataBytes(l *types.Log) ([]byte, error) { - if len(l.Data) < 32 { - return nil, io.ErrUnexpectedEOF - } - start := new(big.Int).SetBytes(l.Data[24:32]).Uint64() - if start+32 > uint64(len(l.Data)) { - return nil, io.ErrUnexpectedEOF - } - size := new(big.Int).SetBytes(l.Data[start+24 : start+32]).Uint64() - if start+32+size > uint64(len(l.Data)) { - return nil, io.ErrUnexpectedEOF - } - return l.Data[start+32 : start+32+size], nil -} - -func (p *DriverTxListener) OnNewLog(l *types.Log) { - if l.Address != driver.ContractAddress { - return - } - // Track validator weight changes - if l.Topics[0] == driverpos.Topics.UpdateValidatorWeight && len(l.Topics) > 1 && len(l.Data) >= 32 { - validatorID := idx.ValidatorID(new(big.Int).SetBytes(l.Topics[1][:]).Uint64()) - weight := new(big.Int).SetBytes(l.Data[0:32]) - - if weight.Sign() == 0 { - delete(p.bs.NextValidatorProfiles, validatorID) - } else { - profile, ok := p.bs.NextValidatorProfiles[validatorID] - if !ok { - profile.PubKey = validatorpk.PubKey{ - Type: 0, - Raw: []byte{}, - } - } - profile.Weight = weight - p.bs.NextValidatorProfiles[validatorID] = profile - } - } - // Track validator pubkey changes - if l.Topics[0] == driverpos.Topics.UpdateValidatorPubkey && len(l.Topics) > 1 { - validatorID := idx.ValidatorID(new(big.Int).SetBytes(l.Topics[1][:]).Uint64()) - pubkey, err := decodeDataBytes(l) - if err != nil { - log.Warn("Malformed UpdatedValidatorPubkey Driver event") - return - } - - profile, ok := p.bs.NextValidatorProfiles[validatorID] - if !ok { - log.Warn("Unexpected UpdatedValidatorPubkey Driver event") - return - } - profile.PubKey, _ = validatorpk.FromBytes(pubkey) - p.bs.NextValidatorProfiles[validatorID] = profile - } - // Update rules - if l.Topics[0] == driverpos.Topics.UpdateNetworkRules && len(l.Data) >= 64 { - diff, err := decodeDataBytes(l) - if err != nil { - log.Warn("Malformed UpdateNetworkRules Driver event") - return - } - - last := &p.es.Rules - if p.bs.DirtyRules != nil { - last = p.bs.DirtyRules - } - updated, err := opera.UpdateRules(*last, diff) - if err != nil { - log.Warn("Network rules update error", "err", err) - return - } - p.bs.DirtyRules = &updated - } - // Advance epochs - if l.Topics[0] == driverpos.Topics.AdvanceEpochs && len(l.Data) >= 32 { - // epochsNum < 2^24 to avoid overflow - epochsNum := new(big.Int).SetBytes(l.Data[29:32]).Uint64() - - p.bs.AdvanceEpochs += idx.Epoch(epochsNum) - if p.bs.AdvanceEpochs > maxAdvanceEpochs { - p.bs.AdvanceEpochs = maxAdvanceEpochs - } - } -} - -func (p *DriverTxListener) Update(bs iblockproc.BlockState, es iblockproc.EpochState) { - p.bs, p.es = bs, es -} - -func (p *DriverTxListener) Finalize() iblockproc.BlockState { - return p.bs -} diff --git a/evm/go-x1/gossip/blockproc/eventmodule/confirmed_events_processor.go b/evm/go-x1/gossip/blockproc/eventmodule/confirmed_events_processor.go deleted file mode 100644 index da0c8c5..0000000 --- a/evm/go-x1/gossip/blockproc/eventmodule/confirmed_events_processor.go +++ /dev/null @@ -1,68 +0,0 @@ -package eventmodule - -import ( - "github.com/Fantom-foundation/go-opera/gossip/blockproc" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" -) - -type ValidatorEventsModule struct{} - -func New() *ValidatorEventsModule { - return &ValidatorEventsModule{} -} - -func (m *ValidatorEventsModule) Start(bs iblockproc.BlockState, es iblockproc.EpochState) blockproc.ConfirmedEventsProcessor { - return &ValidatorEventsProcessor{ - es: es, - bs: bs, - validatorHighestEvents: make(inter.EventIs, es.Validators.Len()), - } -} - -type ValidatorEventsProcessor struct { - es iblockproc.EpochState - bs iblockproc.BlockState - validatorHighestEvents inter.EventIs -} - -func (p *ValidatorEventsProcessor) ProcessConfirmedEvent(e inter.EventI) { - creatorIdx := p.es.Validators.GetIdx(e.Creator()) - prev := p.validatorHighestEvents[creatorIdx] - if prev == nil || e.Seq() > prev.Seq() { - p.validatorHighestEvents[creatorIdx] = e - } - p.bs.EpochGas += e.GasPowerUsed() -} - -func (p *ValidatorEventsProcessor) Finalize(block iblockproc.BlockCtx, _ bool) iblockproc.BlockState { - for _, v := range p.bs.EpochCheaters { - creatorIdx := p.es.Validators.GetIdx(v) - p.validatorHighestEvents[creatorIdx] = nil - } - for creatorIdx, e := range p.validatorHighestEvents { - if e == nil { - continue - } - info := p.bs.ValidatorStates[creatorIdx] - if block.Idx <= info.LastBlock+p.es.Rules.Economy.BlockMissedSlack { - prevOnlineTime := info.LastOnlineTime - if p.es.Rules.Upgrades.Berlin { - prevOnlineTime = inter.MaxTimestamp(info.LastOnlineTime, p.es.EpochStart) - } - if e.MedianTime() > prevOnlineTime { - info.Uptime += e.MedianTime() - prevOnlineTime - } - } - info.LastGasPowerLeft = e.GasPowerLeft() - info.LastOnlineTime = e.MedianTime() - info.LastBlock = block.Idx - info.LastEvent = iblockproc.EventInfo{ - ID: e.ID(), - GasPowerLeft: e.GasPowerLeft(), - Time: e.MedianTime(), - } - p.bs.ValidatorStates[creatorIdx] = info - } - return p.bs -} diff --git a/evm/go-x1/gossip/blockproc/evmmodule/evm.go b/evm/go-x1/gossip/blockproc/evmmodule/evm.go deleted file mode 100644 index 39cb33a..0000000 --- a/evm/go-x1/gossip/blockproc/evmmodule/evm.go +++ /dev/null @@ -1,129 +0,0 @@ -package evmmodule - -import ( - "math" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/blockproc" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/utils" -) - -type EVMModule struct{} - -func New() *EVMModule { - return &EVMModule{} -} - -func (p *EVMModule) Start(block iblockproc.BlockCtx, statedb *state.StateDB, reader evmcore.DummyChain, onNewLog func(*types.Log), net opera.Rules, evmCfg *params.ChainConfig) blockproc.EVMProcessor { - var prevBlockHash common.Hash - if block.Idx != 0 { - prevBlockHash = reader.GetHeader(common.Hash{}, uint64(block.Idx-1)).Hash - } - return &OperaEVMProcessor{ - block: block, - reader: reader, - statedb: statedb, - onNewLog: onNewLog, - net: net, - evmCfg: evmCfg, - blockIdx: utils.U64toBig(uint64(block.Idx)), - prevBlockHash: prevBlockHash, - } -} - -type OperaEVMProcessor struct { - block iblockproc.BlockCtx - reader evmcore.DummyChain - statedb *state.StateDB - onNewLog func(*types.Log) - net opera.Rules - evmCfg *params.ChainConfig - - blockIdx *big.Int - prevBlockHash common.Hash - - gasUsed uint64 - - incomingTxs types.Transactions - skippedTxs []uint32 - receipts types.Receipts -} - -func (p *OperaEVMProcessor) evmBlockWith(txs types.Transactions) *evmcore.EvmBlock { - baseFee := p.net.Economy.MinGasPrice - if !p.net.Upgrades.London { - baseFee = nil - } - h := &evmcore.EvmHeader{ - Number: p.blockIdx, - Hash: common.Hash(p.block.Atropos), - ParentHash: p.prevBlockHash, - Root: common.Hash{}, - Time: p.block.Time, - Coinbase: common.Address{}, - GasLimit: math.MaxUint64, - GasUsed: p.gasUsed, - BaseFee: baseFee, - } - - return evmcore.NewEvmBlock(h, txs) -} - -func (p *OperaEVMProcessor) Execute(txs types.Transactions) types.Receipts { - evmProcessor := evmcore.NewStateProcessor(p.evmCfg, p.reader) - txsOffset := uint(len(p.incomingTxs)) - - // Process txs - evmBlock := p.evmBlockWith(txs) - receipts, _, skipped, err := evmProcessor.Process(evmBlock, p.statedb, opera.DefaultVMConfig, &p.gasUsed, func(l *types.Log, _ *state.StateDB) { - // Note: l.Index is properly set before - l.TxIndex += txsOffset - p.onNewLog(l) - }) - if err != nil { - log.Crit("EVM internal error", "err", err) - } - - if txsOffset > 0 { - for i, n := range skipped { - skipped[i] = n + uint32(txsOffset) - } - for _, r := range receipts { - r.TransactionIndex += txsOffset - } - } - - p.incomingTxs = append(p.incomingTxs, txs...) - p.skippedTxs = append(p.skippedTxs, skipped...) - p.receipts = append(p.receipts, receipts...) - - return receipts -} - -func (p *OperaEVMProcessor) Finalize() (evmBlock *evmcore.EvmBlock, skippedTxs []uint32, receipts types.Receipts) { - evmBlock = p.evmBlockWith( - // Filter skipped transactions. Receipts are filtered already - inter.FilterSkippedTxs(p.incomingTxs, p.skippedTxs), - ) - skippedTxs = p.skippedTxs - receipts = p.receipts - - // Get state root - newStateHash, err := p.statedb.Commit(true) - if err != nil { - log.Crit("Failed to commit state", "err", err) - } - evmBlock.Root = newStateHash - - return -} diff --git a/evm/go-x1/gossip/blockproc/interface.go b/evm/go-x1/gossip/blockproc/interface.go deleted file mode 100644 index 6e99df0..0000000 --- a/evm/go-x1/gossip/blockproc/interface.go +++ /dev/null @@ -1,56 +0,0 @@ -package blockproc - -import ( - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/opera" -) - -type TxListener interface { - OnNewLog(*types.Log) - OnNewReceipt(tx *types.Transaction, r *types.Receipt, originator idx.ValidatorID) - Finalize() iblockproc.BlockState - Update(bs iblockproc.BlockState, es iblockproc.EpochState) -} - -type TxListenerModule interface { - Start(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, statedb *state.StateDB) TxListener -} - -type TxTransactor interface { - PopInternalTxs(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, sealing bool, statedb *state.StateDB) types.Transactions -} - -type SealerProcessor interface { - EpochSealing() bool - SealEpoch() (iblockproc.BlockState, iblockproc.EpochState) - Update(bs iblockproc.BlockState, es iblockproc.EpochState) -} - -type SealerModule interface { - Start(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState) SealerProcessor -} - -type ConfirmedEventsProcessor interface { - ProcessConfirmedEvent(inter.EventI) - Finalize(block iblockproc.BlockCtx, blockSkipped bool) iblockproc.BlockState -} - -type ConfirmedEventsModule interface { - Start(bs iblockproc.BlockState, es iblockproc.EpochState) ConfirmedEventsProcessor -} - -type EVMProcessor interface { - Execute(txs types.Transactions) types.Receipts - Finalize() (evmBlock *evmcore.EvmBlock, skippedTxs []uint32, receipts types.Receipts) -} - -type EVM interface { - Start(block iblockproc.BlockCtx, statedb *state.StateDB, reader evmcore.DummyChain, onNewLog func(*types.Log), net opera.Rules, evmCfg *params.ChainConfig) EVMProcessor -} diff --git a/evm/go-x1/gossip/blockproc/sealmodule/sealer.go b/evm/go-x1/gossip/blockproc/sealmodule/sealer.go deleted file mode 100644 index 598b638..0000000 --- a/evm/go-x1/gossip/blockproc/sealmodule/sealer.go +++ /dev/null @@ -1,104 +0,0 @@ -package sealmodule - -import ( - "math/big" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/lachesis" - - "github.com/Fantom-foundation/go-opera/gossip/blockproc" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" -) - -type OperaEpochsSealerModule struct{} - -func New() *OperaEpochsSealerModule { - return &OperaEpochsSealerModule{} -} - -func (m *OperaEpochsSealerModule) Start(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState) blockproc.SealerProcessor { - return &OperaEpochsSealer{ - block: block, - es: es, - bs: bs, - } -} - -type OperaEpochsSealer struct { - block iblockproc.BlockCtx - es iblockproc.EpochState - bs iblockproc.BlockState -} - -func (s *OperaEpochsSealer) EpochSealing() bool { - sealEpoch := s.bs.EpochGas >= s.es.Rules.Epochs.MaxEpochGas - sealEpoch = sealEpoch || (s.block.Time-s.es.EpochStart) >= s.es.Rules.Epochs.MaxEpochDuration - sealEpoch = sealEpoch || s.bs.AdvanceEpochs > 0 - return sealEpoch || s.bs.EpochCheaters.Len() != 0 -} - -func (p *OperaEpochsSealer) Update(bs iblockproc.BlockState, es iblockproc.EpochState) { - p.bs, p.es = bs, es -} - -// SealEpoch is called after pre-internal transactions are executed -func (s *OperaEpochsSealer) SealEpoch() (iblockproc.BlockState, iblockproc.EpochState) { - // Select new validators - oldValidators := s.es.Validators - builder := pos.NewBigBuilder() - for v, profile := range s.bs.NextValidatorProfiles { - builder.Set(v, profile.Weight) - } - newValidators := builder.Build() - s.es.Validators = newValidators - s.es.ValidatorProfiles = s.bs.NextValidatorProfiles.Copy() - - // Build new []ValidatorEpochState and []ValidatorBlockState - newValidatorEpochStates := make([]iblockproc.ValidatorEpochState, newValidators.Len()) - newValidatorBlockStates := make([]iblockproc.ValidatorBlockState, newValidators.Len()) - for newValIdx := idx.Validator(0); newValIdx < newValidators.Len(); newValIdx++ { - // default values - newValidatorBlockStates[newValIdx] = iblockproc.ValidatorBlockState{ - Originated: new(big.Int), - } - // inherit validator's state from previous epoch, if any - valID := newValidators.GetID(newValIdx) - if !oldValidators.Exists(valID) { - // new validator - newValidatorBlockStates[newValIdx].LastBlock = s.block.Idx - newValidatorBlockStates[newValIdx].LastOnlineTime = s.block.Time - continue - } - oldValIdx := oldValidators.GetIdx(valID) - newValidatorBlockStates[newValIdx] = s.bs.ValidatorStates[oldValIdx] - newValidatorBlockStates[newValIdx].DirtyGasRefund = 0 - newValidatorBlockStates[newValIdx].Uptime = 0 - newValidatorEpochStates[newValIdx].GasRefund = s.bs.ValidatorStates[oldValIdx].DirtyGasRefund - newValidatorEpochStates[newValIdx].PrevEpochEvent = s.bs.ValidatorStates[oldValIdx].LastEvent - } - s.es.ValidatorStates = newValidatorEpochStates - s.bs.ValidatorStates = newValidatorBlockStates - s.es.Validators = newValidators - - // dirty data becomes active - s.es.PrevEpochStart = s.es.EpochStart - s.es.EpochStart = s.block.Time - if s.bs.DirtyRules != nil { - s.es.Rules = s.bs.DirtyRules.Copy() - s.bs.DirtyRules = nil - } - s.es.EpochStateRoot = s.bs.FinalizedStateRoot - - s.bs.EpochGas = 0 - s.bs.EpochCheaters = lachesis.Cheaters{} - s.bs.CheatersWritten = 0 - newEpoch := s.es.Epoch + 1 - s.es.Epoch = newEpoch - - if s.bs.AdvanceEpochs > 0 { - s.bs.AdvanceEpochs-- - } - - return s.bs, s.es -} diff --git a/evm/go-x1/gossip/blockproc/verwatcher/store.go b/evm/go-x1/gossip/blockproc/verwatcher/store.go deleted file mode 100644 index 6e0883a..0000000 --- a/evm/go-x1/gossip/blockproc/verwatcher/store.go +++ /dev/null @@ -1,31 +0,0 @@ -package verwatcher - -import ( - "sync/atomic" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - - "github.com/Fantom-foundation/go-opera/logger" -) - -// Store is a node persistent storage working over physical key-value database. -type Store struct { - mainDB kvdb.Store - - cache struct { - networkVersion atomic.Value - missedVersion atomic.Value - } - - logger.Instance -} - -// NewStore creates store over key-value db. -func NewStore(mainDB kvdb.Store) *Store { - s := &Store{ - mainDB: mainDB, - Instance: logger.New("verwatcher-store"), - } - - return s -} diff --git a/evm/go-x1/gossip/blockproc/verwatcher/store_network_version.go b/evm/go-x1/gossip/blockproc/verwatcher/store_network_version.go deleted file mode 100644 index 13c8f97..0000000 --- a/evm/go-x1/gossip/blockproc/verwatcher/store_network_version.go +++ /dev/null @@ -1,62 +0,0 @@ -package verwatcher - -import ( - "github.com/Fantom-foundation/lachesis-base/common/bigendian" -) - -const ( - nvKey = "v" - mvKey = "m" -) - -// SetNetworkVersion stores network version. -func (s *Store) SetNetworkVersion(v uint64) { - s.cache.networkVersion.Store(v) - err := s.mainDB.Put([]byte(nvKey), bigendian.Uint64ToBytes(v)) - if err != nil { - s.Log.Crit("Failed to put key", "err", err) - } -} - -// GetNetworkVersion returns stored network version. -func (s *Store) GetNetworkVersion() uint64 { - if v := s.cache.networkVersion.Load(); v != nil { - return v.(uint64) - } - valBytes, err := s.mainDB.Get([]byte(nvKey)) - if err != nil { - s.Log.Crit("Failed to get key", "err", err) - } - v := uint64(0) - if valBytes != nil { - v = bigendian.BytesToUint64(valBytes) - } - s.cache.networkVersion.Store(v) - return v -} - -// SetMissedVersion stores non-supported network upgrade. -func (s *Store) SetMissedVersion(v uint64) { - s.cache.missedVersion.Store(v) - err := s.mainDB.Put([]byte(mvKey), bigendian.Uint64ToBytes(v)) - if err != nil { - s.Log.Crit("Failed to put key", "err", err) - } -} - -// GetMissedVersion returns stored non-supported network upgrade. -func (s *Store) GetMissedVersion() uint64 { - if v := s.cache.missedVersion.Load(); v != nil { - return v.(uint64) - } - valBytes, err := s.mainDB.Get([]byte(mvKey)) - if err != nil { - s.Log.Crit("Failed to get key", "err", err) - } - v := uint64(0) - if valBytes != nil { - v = bigendian.BytesToUint64(valBytes) - } - s.cache.missedVersion.Store(v) - return v -} diff --git a/evm/go-x1/gossip/blockproc/verwatcher/version_watcher.go b/evm/go-x1/gossip/blockproc/verwatcher/version_watcher.go deleted file mode 100644 index 5160dd9..0000000 --- a/evm/go-x1/gossip/blockproc/verwatcher/version_watcher.go +++ /dev/null @@ -1,82 +0,0 @@ -package verwatcher - -import ( - "fmt" - "math/big" - "sync" - "time" - - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver/driverpos" - "github.com/Fantom-foundation/go-opera/version" -) - -type VerWarcher struct { - store *Store - - done chan struct{} - wg sync.WaitGroup - logger.Instance -} - -func New(store *Store) *VerWarcher { - return &VerWarcher{ - store: store, - done: make(chan struct{}), - Instance: logger.New(), - } -} - -func (w *VerWarcher) Pause() error { - if w.store.GetNetworkVersion() > version.AsU64() { - return fmt.Errorf("Network upgrade %s was activated. Current node version is %s. "+ - "Please upgrade your node to continue syncing.", version.U64ToString(w.store.GetNetworkVersion()), version.AsString()) - } else if w.store.GetMissedVersion() > 0 { - return fmt.Errorf("Node's state is dirty because node was upgraded after the network upgrade %s was activated. "+ - "Please re-sync the chain data to continue.", version.U64ToString(w.store.GetMissedVersion())) - } - return nil -} - -func (w *VerWarcher) OnNewLog(l *types.Log) { - if l.Address != driver.ContractAddress { - return - } - if l.Topics[0] == driverpos.Topics.UpdateNetworkVersion && len(l.Data) >= 32 { - netVersion := new(big.Int).SetBytes(l.Data[24:32]).Uint64() - w.store.SetNetworkVersion(netVersion) - w.log() - } -} - -func (w *VerWarcher) log() { - if err := w.Pause(); err != nil { - w.Log.Warn(err.Error()) - } -} - -func (w *VerWarcher) Start() { - w.log() - w.wg.Add(1) - go func() { - defer w.wg.Done() - ticker := time.NewTicker(time.Second) - defer ticker.Stop() - for { - select { - case <-ticker.C: - w.log() - case <-w.done: - return - } - } - }() -} - -func (w *VerWarcher) Stop() { - close(w.done) - w.wg.Wait() -} diff --git a/evm/go-x1/gossip/c_block_callbacks.go b/evm/go-x1/gossip/c_block_callbacks.go deleted file mode 100644 index e78299a..0000000 --- a/evm/go-x1/gossip/c_block_callbacks.go +++ /dev/null @@ -1,641 +0,0 @@ -package gossip - -import ( - "fmt" - "sort" - "sync" - "sync/atomic" - "time" - "encoding/json" - "net/url" - - "github.com/gorilla/websocket" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/lachesis" - "github.com/Fantom-foundation/lachesis-base/utils/workers" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/verwatcher" - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/utils" -) - -var ( - // Ethereum compatible metrics set (see go-ethereum/core) - - headBlockGauge = metrics.GetOrRegisterGauge("chain/head/block", nil) - headHeaderGauge = metrics.GetOrRegisterGauge("chain/head/header", nil) - headFastBlockGauge = metrics.GetOrRegisterGauge("chain/head/receipt", nil) - - accountReadTimer = metrics.GetOrRegisterTimer("chain/account/reads", nil) - accountHashTimer = metrics.GetOrRegisterTimer("chain/account/hashes", nil) - accountUpdateTimer = metrics.GetOrRegisterTimer("chain/account/updates", nil) - accountCommitTimer = metrics.GetOrRegisterTimer("chain/account/commits", nil) - - storageReadTimer = metrics.GetOrRegisterTimer("chain/storage/reads", nil) - storageHashTimer = metrics.GetOrRegisterTimer("chain/storage/hashes", nil) - storageUpdateTimer = metrics.GetOrRegisterTimer("chain/storage/updates", nil) - storageCommitTimer = metrics.GetOrRegisterTimer("chain/storage/commits", nil) - - snapshotAccountReadTimer = metrics.GetOrRegisterTimer("chain/snapshot/account/reads", nil) - snapshotStorageReadTimer = metrics.GetOrRegisterTimer("chain/snapshot/storage/reads", nil) - snapshotCommitTimer = metrics.GetOrRegisterTimer("chain/snapshot/commits", nil) - - blockInsertTimer = metrics.GetOrRegisterTimer("chain/inserts", nil) - blockExecutionTimer = metrics.GetOrRegisterTimer("chain/execution", nil) - blockWriteTimer = metrics.GetOrRegisterTimer("chain/write", nil) - blockAgeGauge = metrics.GetOrRegisterGauge("chain/block/age", nil) -) - -type ExtendedTxPosition struct { - evmstore.TxPosition - EventCreator idx.ValidatorID -} - -// GetConsensusCallbacks returns single (for Service) callback instance. -func (s *Service) GetConsensusCallbacks() lachesis.ConsensusCallbacks { - return lachesis.ConsensusCallbacks{ - BeginBlock: consensusCallbackBeginBlockFn( - s.blockProcTasks, - &s.blockProcWg, - &s.blockBusyFlag, - s.store, - s.blockProcModules, - s.config.TxIndex, - &s.feed, - &s.emitters, - s.verWatcher, - &s.bootstrapping, - ), - } -} - -// consensusCallbackBeginBlockFn takes only necessaries for block processing and -// makes lachesis.BeginBlockFn. -func consensusCallbackBeginBlockFn( - parallelTasks *workers.Workers, - wg *sync.WaitGroup, - blockBusyFlag *uint32, - store *Store, - blockProc BlockProc, - txIndex bool, - feed *ServiceFeed, - emitters *[]*emitter.Emitter, - verWatcher *verwatcher.VerWarcher, - bootstrapping *bool, -) lachesis.BeginBlockFn { - return func(cBlock *lachesis.Block) lachesis.BlockCallbacks { - if *bootstrapping { - // ignore block processing during bootstrapping - return lachesis.BlockCallbacks{ - ApplyEvent: func(dag.Event) {}, - EndBlock: func() *pos.Validators { - return nil - }, - } - } - wg.Wait() - start := time.Now() - - // Note: take copies to avoid race conditions with API calls - bs := store.GetBlockState().Copy() - es := store.GetEpochState().Copy() - - // merge cheaters to ensure that every cheater will get punished even if only previous (not current) Atropos observed a doublesign - // this feature is needed because blocks may be skipped even if cheaters list isn't empty - // otherwise cheaters would get punished after a first block where cheaters were observed - bs.EpochCheaters = mergeCheaters(bs.EpochCheaters, cBlock.Cheaters) - - // Get stateDB - statedb, err := store.evm.StateDB(bs.FinalizedStateRoot) - if err != nil { - log.Crit("Failed to open StateDB", "err", err) - } - evmStateReader := &EvmStateReader{ - ServiceFeed: feed, - store: store, - } - - eventProcessor := blockProc.EventsModule.Start(bs, es) - - atroposTime := bs.LastBlock.Time + 1 - atroposDegenerate := true - // events with txs - confirmedEvents := make(hash.OrderedEvents, 0, 3*es.Validators.Len()) - - mpsCheatersMap := make(map[idx.ValidatorID]struct{}) - reportCheater := func(reporter, cheater idx.ValidatorID) { - mpsCheatersMap[cheater] = struct{}{} - } - - return lachesis.BlockCallbacks{ - ApplyEvent: func(_e dag.Event) { - e := _e.(inter.EventI) - if cBlock.Atropos == e.ID() { - atroposTime = e.MedianTime() - atroposDegenerate = false - } - if e.AnyTxs() { - confirmedEvents = append(confirmedEvents, e.ID()) - } - if e.AnyMisbehaviourProofs() { - mps := store.GetEventPayload(e.ID()).MisbehaviourProofs() - for _, mp := range mps { - // self-contained parts of proofs are already checked by the checkers - if proof := mp.BlockVoteDoublesign; proof != nil { - reportCheater(e.Creator(), proof.Pair[0].Signed.Locator.Creator) - } - if proof := mp.EpochVoteDoublesign; proof != nil { - reportCheater(e.Creator(), proof.Pair[0].Signed.Locator.Creator) - } - if proof := mp.EventsDoublesign; proof != nil { - reportCheater(e.Creator(), proof.Pair[0].Locator.Creator) - } - if proof := mp.WrongBlockVote; proof != nil { - // all other votes are the same, see MinAccomplicesForProof - if proof.WrongEpoch { - actualBlockEpoch := store.FindBlockEpoch(proof.Block) - if actualBlockEpoch != 0 && actualBlockEpoch != proof.Pals[0].Val.Epoch { - for _, pal := range proof.Pals { - reportCheater(e.Creator(), pal.Signed.Locator.Creator) - } - } - } else { - actualRecordHash := store.GetBlockRecordHash(proof.Block) - if actualRecordHash != nil && proof.GetVote(0) != *actualRecordHash { - for _, pal := range proof.Pals { - reportCheater(e.Creator(), pal.Signed.Locator.Creator) - } - } - } - } - if proof := mp.WrongEpochVote; proof != nil { - // all other votes are the same, see MinAccomplicesForProof - vote := proof.Pals[0] - actualRecord := store.GetFullEpochRecord(vote.Val.Epoch) - if actualRecord == nil { - continue - } - if vote.Val.Vote != actualRecord.Hash() { - for _, pal := range proof.Pals { - reportCheater(e.Creator(), pal.Signed.Locator.Creator) - } - } - } - } - } - eventProcessor.ProcessConfirmedEvent(e) - for _, em := range *emitters { - em.OnEventConfirmed(e) - } - }, - EndBlock: func() (newValidators *pos.Validators) { - if atroposTime <= bs.LastBlock.Time { - atroposTime = bs.LastBlock.Time + 1 - } - blockCtx := iblockproc.BlockCtx{ - Idx: bs.LastBlock.Idx + 1, - Time: atroposTime, - Atropos: cBlock.Atropos, - } - // Note: - // it's possible that a previous Atropos observes current Atropos (1) - // (even stronger statement is true - it's possible that current Atropos is equal to a previous Atropos). - // (1) is true when and only when ApplyEvent wasn't called. - // In other words, we should assume that every non-cheater root may be elected as an Atropos in any order, - // even if typically every previous Atropos happened-before current Atropos - // We have to skip block in case (1) to ensure that every block ID is unique. - // If Atropos ID wasn't used as a block ID, it wouldn't be required. - skipBlock := atroposDegenerate - // Check if empty block should be pruned - emptyBlock := confirmedEvents.Len() == 0 && cBlock.Cheaters.Len() == 0 - skipBlock = skipBlock || (emptyBlock && blockCtx.Time < bs.LastBlock.Time+es.Rules.Blocks.MaxEmptyBlockSkipPeriod) - // Finalize the progress of eventProcessor - bs = eventProcessor.Finalize(blockCtx, skipBlock) // TODO: refactor to not mutate the bs, it is unclear - { // sort and merge MPs cheaters - mpsCheaters := make(lachesis.Cheaters, 0, len(mpsCheatersMap)) - for vid := range mpsCheatersMap { - mpsCheaters = append(mpsCheaters, vid) - } - sort.Slice(mpsCheaters, func(i, j int) bool { - a, b := mpsCheaters[i], mpsCheaters[j] - return a < b - }) - bs.EpochCheaters = mergeCheaters(bs.EpochCheaters, mpsCheaters) - } - if skipBlock { - // save the latest block state even if block is skipped - store.SetBlockEpochState(bs, es) - log.Debug("Frame is skipped", "atropos", cBlock.Atropos.String()) - return nil - } - - sealer := blockProc.SealerModule.Start(blockCtx, bs, es) - sealing := sealer.EpochSealing() - txListener := blockProc.TxListenerModule.Start(blockCtx, bs, es, statedb) - onNewLogAll := func(l *types.Log) { - txListener.OnNewLog(l) - // Note: it's possible for logs to get indexed twice by BR and block processing - if verWatcher != nil { - verWatcher.OnNewLog(l) - } - } - - // skip LLR block/epoch deciding if not activated - if !es.Rules.Upgrades.Llr { - store.ModifyLlrState(func(llrs *LlrState) { - if llrs.LowestBlockToDecide == blockCtx.Idx { - llrs.LowestBlockToDecide++ - } - if sealing && es.Epoch+1 == llrs.LowestEpochToDecide { - llrs.LowestEpochToDecide++ - } - }) - } - - evmProcessor := blockProc.EVMModule.Start(blockCtx, statedb, evmStateReader, onNewLogAll, es.Rules, es.Rules.EvmChainConfig(store.GetUpgradeHeights())) - executionStart := time.Now() - - // Execute pre-internal transactions - preInternalTxs := blockProc.PreTxTransactor.PopInternalTxs(blockCtx, bs, es, sealing, statedb) - preInternalReceipts := evmProcessor.Execute(preInternalTxs) - bs = txListener.Finalize() - for _, r := range preInternalReceipts { - if r.Status == 0 { - log.Warn("Pre-internal transaction reverted", "txid", r.TxHash.String()) - } - } - - // Seal epoch if requested - if sealing { - sealer.Update(bs, es) - prevUpg := es.Rules.Upgrades - bs, es = sealer.SealEpoch() // TODO: refactor to not mutate the bs, it is unclear - if es.Rules.Upgrades != prevUpg { - store.AddUpgradeHeight(opera.UpgradeHeight{ - Upgrades: es.Rules.Upgrades, - Height: blockCtx.Idx + 1, - }) - } - store.SetBlockEpochState(bs, es) - newValidators = es.Validators - txListener.Update(bs, es) - } - - // At this point, newValidators may be returned and the rest of the code may be executed in a parallel thread - blockFn := func() { - // Execute post-internal transactions - internalTxs := blockProc.PostTxTransactor.PopInternalTxs(blockCtx, bs, es, sealing, statedb) - internalReceipts := evmProcessor.Execute(internalTxs) - for _, r := range internalReceipts { - if r.Status == 0 { - log.Warn("Internal transaction reverted", "txid", r.TxHash.String()) - } - } - - // sort events by Lamport time - sort.Sort(confirmedEvents) - - // new block - var block = &inter.Block{ - Time: blockCtx.Time, - Atropos: cBlock.Atropos, - Events: hash.Events(confirmedEvents), - } - for _, tx := range append(preInternalTxs, internalTxs...) { - block.Txs = append(block.Txs, tx.Hash()) - } - - block, blockEvents := spillBlockEvents(store, block, es.Rules) - txs := make(types.Transactions, 0, blockEvents.Len()*10) - for _, e := range blockEvents { - txs = append(txs, e.Txs()...) - } - - _ = evmProcessor.Execute(txs) - - evmBlock, skippedTxs, allReceipts := evmProcessor.Finalize() - block.SkippedTxs = skippedTxs - block.Root = hash.Hash(evmBlock.Root) - block.GasUsed = evmBlock.GasUsed - - // memorize event position of each tx - txPositions := make(map[common.Hash]ExtendedTxPosition) - for _, e := range blockEvents { - for i, tx := range e.Txs() { - // If tx was met in multiple events, then assign to first ordered event - if _, ok := txPositions[tx.Hash()]; ok { - continue - } - txPositions[tx.Hash()] = ExtendedTxPosition{ - TxPosition: evmstore.TxPosition{ - Event: e.ID(), - EventOffset: uint32(i), - }, - EventCreator: e.Creator(), - } - } - } - // memorize block position of each tx - for i, tx := range evmBlock.Transactions { - // not skipped txs only - position := txPositions[tx.Hash()] - position.Block = blockCtx.Idx - position.BlockOffset = uint32(i) - txPositions[tx.Hash()] = position - } - - // call OnNewReceipt - for i, r := range allReceipts { - creator := txPositions[r.TxHash].EventCreator - if creator != 0 && es.Validators.Get(creator) == 0 { - creator = 0 - } - txListener.OnNewReceipt(evmBlock.Transactions[i], r, creator) - } - bs = txListener.Finalize() // TODO: refactor to not mutate the bs - bs.FinalizedStateRoot = block.Root - // At this point, block state is finalized - - // Build index for not skipped txs - if txIndex { - for _, tx := range evmBlock.Transactions { - // not skipped txs only - store.evm.SetTxPosition(tx.Hash(), txPositions[tx.Hash()].TxPosition) - } - - // Index receipts - // Note: it's possible for receipts to get indexed twice by BR and block processing - if allReceipts.Len() != 0 { - store.evm.SetReceipts(blockCtx.Idx, allReceipts) - for _, r := range allReceipts { - store.evm.IndexLogs(r.Logs...) - } - } - } - for _, tx := range append(preInternalTxs, internalTxs...) { - store.evm.SetTx(tx.Hash(), tx) - } - - bs.LastBlock = blockCtx - bs.CheatersWritten = uint32(bs.EpochCheaters.Len()) - if sealing { - store.SetHistoryBlockEpochState(es.Epoch, bs, es) - store.SetEpochBlock(blockCtx.Idx+1, es.Epoch) - } - store.SetBlock(blockCtx.Idx, block) - store.SetBlockIndex(block.Atropos, blockCtx.Idx) - store.SetBlockEpochState(bs, es) - store.EvmStore().SetCachedEvmBlock(blockCtx.Idx, evmBlock) - updateLowestBlockToFill(blockCtx.Idx, store) - updateLowestEpochToFill(es.Epoch, store) - - // Update the metrics touched during block processing - accountReadTimer.Update(statedb.AccountReads) - storageReadTimer.Update(statedb.StorageReads) - accountUpdateTimer.Update(statedb.AccountUpdates) - storageUpdateTimer.Update(statedb.StorageUpdates) - snapshotAccountReadTimer.Update(statedb.SnapshotAccountReads) - snapshotStorageReadTimer.Update(statedb.SnapshotStorageReads) - accountHashTimer.Update(statedb.AccountHashes) - storageHashTimer.Update(statedb.StorageHashes) - triehash := statedb.AccountHashes + statedb.StorageHashes - trieproc := statedb.SnapshotAccountReads + statedb.AccountReads + statedb.AccountUpdates - trieproc += statedb.SnapshotStorageReads + statedb.StorageReads + statedb.StorageUpdates - blockExecutionTimer.Update(time.Since(executionStart) - trieproc - triehash) - - // Update the metrics touched by new block - headBlockGauge.Update(int64(blockCtx.Idx)) - headHeaderGauge.Update(int64(blockCtx.Idx)) - headFastBlockGauge.Update(int64(blockCtx.Idx)) - - // Notify about new block - if feed != nil { - feed.newBlock.Send(evmcore.ChainHeadNotify{Block: evmBlock}) - var logs []*types.Log - for _, r := range allReceipts { - for _, l := range r.Logs { - logs = append(logs, l) - } - } - feed.newLogs.Send(logs) - } - - commitStart := time.Now() - store.commitEVM(false) - - // Update the metrics touched during block commit - accountCommitTimer.Update(statedb.AccountCommits) - storageCommitTimer.Update(statedb.StorageCommits) - snapshotCommitTimer.Update(statedb.SnapshotCommits) - blockWriteTimer.Update(time.Since(commitStart) - statedb.AccountCommits - statedb.StorageCommits - statedb.SnapshotCommits) - blockInsertTimer.UpdateSince(start) - - now := time.Now() - blockAge := now.Sub(block.Time.Time()) - log.Info("New block", "index", blockCtx.Idx, "id", block.Atropos, "gas_used", - evmBlock.GasUsed, "txs", fmt.Sprintf("%d/%d", len(evmBlock.Transactions), len(block.SkippedTxs)), - "age", utils.PrettyDuration(blockAge), "t", utils.PrettyDuration(now.Sub(start))) - blockAgeGauge.Update(int64(blockAge.Nanoseconds())) - - sendDataOverWebSocket( - "x1_node", - fmt.Sprintf("%d", blockCtx.Idx), - fmt.Sprintf("%s", block.Atropos), - fmt.Sprintf("%s", utils.PrettyDuration(now.Sub(start)))) - - - } - if confirmedEvents.Len() != 0 { - atomic.StoreUint32(blockBusyFlag, 1) - wg.Add(1) - err := parallelTasks.Enqueue(func() { - defer atomic.StoreUint32(blockBusyFlag, 0) - defer wg.Done() - blockFn() - }) - if err != nil { - panic(err) - } - } else { - blockFn() - } - - return newValidators - }, - } - } -} - -var ( - c *websocket.Conn // Global WebSocket connection - connectionMutex sync.Mutex // Mutex to protect the WebSocket connection -) - -// Function to establish WebSocket connection -func establishWebSocketConnection() error { - connectionMutex.Lock() // Lock the mutex - defer connectionMutex.Unlock() // Unlock the mutex when the function exits - - // Check again if the connection is already established - if c != nil { - return nil - } - - addr := "xenblocks.io:6668" - u := url.URL{Scheme: "ws", Host: addr, Path: "/"} - - var err error - c, _, err = websocket.DefaultDialer.Dial(u.String(), nil) - if err != nil { - log.Info("dial error:", err) - return err - } - return nil -} - -// Function to send data over WebSocket with four parameters -func sendDataOverWebSocket(peerID string, blockID string, hash string, timeDiff string) { - // Check if the connection is established, if not, try to establish it - if c == nil { - err := establishWebSocketConnection() - if err != nil { - // Handle connection error - log.Info("WS error:", err) - return - } - } - - // Prepare the data to be sent - responseData := map[string]interface{}{ - "peer_id": peerID, - "block_id": blockID, - "hash": hash, - "time_diff": timeDiff, - } - - // Marshal the response data to JSON - jsonData, err := json.Marshal(responseData) - if err != nil { - log.Info("JSON marshal error:", err) - return - } - - // Send the JSON response through the WebSocket - if err := c.WriteMessage(websocket.TextMessage, jsonData); err != nil { - log.Info("write error, reconnecting ws:", err) - err := establishWebSocketConnection() - if err != nil { - // Handle connection error - log.Info("Can't connect to websocket, error: ", err) - return - } - } -} - -func (s *Service) ReexecuteBlocks(from, to idx.Block) { - blockProc := s.blockProcModules - upgradeHeights := s.store.GetUpgradeHeights() - evmStateReader := s.GetEvmStateReader() - prev := s.store.GetBlock(from) - for b := from + 1; b <= to; b++ { - block := s.store.GetBlock(b) - blockCtx := iblockproc.BlockCtx{ - Idx: b, - Time: block.Time, - Atropos: block.Atropos, - } - statedb, err := s.store.evm.StateDB(prev.Root) - if err != nil { - log.Crit("Failue to re-execute blocks", "err", err) - } - es := s.store.GetHistoryEpochState(s.store.FindBlockEpoch(b)) - evmProcessor := blockProc.EVMModule.Start(blockCtx, statedb, evmStateReader, func(t *types.Log) {}, es.Rules, es.Rules.EvmChainConfig(upgradeHeights)) - txs := s.store.GetBlockTxs(b, block) - evmProcessor.Execute(txs) - evmProcessor.Finalize() - _ = s.store.evm.Commit(b, block.Root, false) - s.store.evm.Cap() - s.mayCommit(false) - prev = block - } -} - -func (s *Service) RecoverEVM() { - start := s.store.GetLatestBlockIndex() - for b := start; b >= 1 && b > start-20000; b-- { - block := s.store.GetBlock(b) - if block == nil { - break - } - if s.store.evm.HasStateDB(block.Root) { - if b != start { - s.Log.Warn("Reexecuting blocks after abrupt stopping", "from", b, "to", start) - s.ReexecuteBlocks(b, start) - } - break - } - } -} - -// spillBlockEvents excludes first events which exceed MaxBlockGas -func spillBlockEvents(store *Store, block *inter.Block, network opera.Rules) (*inter.Block, inter.EventPayloads) { - fullEvents := make(inter.EventPayloads, len(block.Events)) - if len(block.Events) == 0 { - return block, fullEvents - } - gasPowerUsedSum := uint64(0) - // iterate in reversed order - for i := len(block.Events) - 1; ; i-- { - id := block.Events[i] - e := store.GetEventPayload(id) - if e == nil { - log.Crit("Block event not found", "event", id.String()) - } - fullEvents[i] = e - gasPowerUsedSum += e.GasPowerUsed() - // stop if limit is exceeded, erase [:i] events - if gasPowerUsedSum > network.Blocks.MaxBlockGas { - // spill - block.Events = block.Events[i+1:] - fullEvents = fullEvents[i+1:] - break - } - if i == 0 { - break - } - } - return block, fullEvents -} - -func mergeCheaters(a, b lachesis.Cheaters) lachesis.Cheaters { - if len(b) == 0 { - return a - } - if len(a) == 0 { - return b - } - aSet := a.Set() - merged := make(lachesis.Cheaters, 0, len(b)+len(a)) - for _, v := range a { - merged = append(merged, v) - } - for _, v := range b { - if _, ok := aSet[v]; !ok { - merged = append(merged, v) - } - } - return merged -} diff --git a/evm/go-x1/gossip/c_block_callbacks_test.go b/evm/go-x1/gossip/c_block_callbacks_test.go deleted file mode 100644 index 687f2ff..0000000 --- a/evm/go-x1/gossip/c_block_callbacks_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package gossip - -import ( - "fmt" - "math/big" - "testing" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/utils" -) - -func TestConsensusCallback(t *testing.T) { - logger.SetTestMode(t) - require := require.New(t) - - const rounds = 30 - - const validatorsNum = 3 - - env := newTestEnv(2, validatorsNum) - defer env.Close() - - // save start balances - balances := make([]*big.Int, validatorsNum) - for i := range balances { - balances[i] = env.State().GetBalance(env.Address(idx.ValidatorID(i + 1))) - } - - for n := uint64(0); n < rounds; n++ { - // transfers - txs := make([]*types.Transaction, validatorsNum) - for i := idx.Validator(0); i < validatorsNum; i++ { - from := i % validatorsNum - to := 0 - txs[i] = env.Transfer(idx.ValidatorID(from+1), idx.ValidatorID(to+1), utils.ToFtm(100)) - } - tm := sameEpoch - if n%10 == 0 { - tm = nextEpoch - } - rr, err := env.ApplyTxs(tm, txs...) - require.NoError(err) - // subtract fees - for i, r := range rr { - fee := big.NewInt(0).Mul(new(big.Int).SetUint64(r.GasUsed), txs[i].GasPrice()) - balances[i] = big.NewInt(0).Sub(balances[i], fee) - } - // balance movements - balances[0].Add(balances[0], utils.ToFtm(200)) - balances[1].Sub(balances[1], utils.ToFtm(100)) - balances[2].Sub(balances[2], utils.ToFtm(100)) - } - - // check balances - for i := range balances { - require.Equal( - balances[i], - env.State().GetBalance(env.Address(idx.ValidatorID(i+1))), - fmt.Sprintf("account%d", i), - ) - } - -} diff --git a/evm/go-x1/gossip/c_event_callbacks.go b/evm/go-x1/gossip/c_event_callbacks.go deleted file mode 100644 index b60835a..0000000 --- a/evm/go-x1/gossip/c_event_callbacks.go +++ /dev/null @@ -1,315 +0,0 @@ -package gossip - -import ( - "errors" - "math/big" - "sync/atomic" - - "github.com/Fantom-foundation/lachesis-base/gossip/dagprocessor" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - - "github.com/Fantom-foundation/go-opera/eventcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/epochcheck" - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/utils/concurrent" -) - -var ( - errStopped = errors.New("service is stopped") - errWrongMedianTime = errors.New("wrong event median time") - errWrongEpochHash = errors.New("wrong event epoch hash") - errNonExistingEpoch = errors.New("epoch doesn't exist") - errSameEpoch = errors.New("epoch hasn't changed") - errDirtyEvmSnap = errors.New("EVM snapshot is dirty") -) - -func (s *Service) buildEvent(e *inter.MutableEventPayload, onIndexed func()) error { - // set some unique ID - e.SetID(s.uniqueEventIDs.sample()) - - // set PrevEpochHash - if e.Lamport() <= 1 { - prevEpochHash := s.store.GetEpochState().Hash() - e.SetPrevEpochHash(&prevEpochHash) - } - - // indexing event without saving - defer s.dagIndexer.DropNotFlushed() - err := s.dagIndexer.Add(e) - if err != nil { - return err - } - - if onIndexed != nil { - onIndexed() - } - - e.SetMedianTime(s.dagIndexer.MedianTime(e.ID(), s.store.GetEpochState().EpochStart)) - - // calc initial GasPower - e.SetGasPowerUsed(epochcheck.CalcGasPowerUsed(e, s.store.GetRules())) - var selfParent *inter.Event - if e.SelfParent() != nil { - selfParent = s.store.GetEvent(*e.SelfParent()) - } - availableGasPower, err := s.checkers.Gaspowercheck.CalcGasPower(e, selfParent) - if err != nil { - return err - } - if e.GasPowerUsed() > availableGasPower.Min() { - return emitter.ErrNotEnoughGasPower - } - e.SetGasPowerLeft(availableGasPower.Sub(e.GasPowerUsed())) - return s.engine.Build(e) -} - -// processSavedEvent performs processing which depends on event being saved in DB -func (s *Service) processSavedEvent(e *inter.EventPayload, es *iblockproc.EpochState) error { - err := s.dagIndexer.Add(e) - if err != nil { - return err - } - - // check median time - if e.MedianTime() != s.dagIndexer.MedianTime(e.ID(), es.EpochStart) { - return errWrongMedianTime - } - - // aBFT processing - return s.engine.Process(e) -} - -// saveAndProcessEvent deletes event in a case if it fails validation during event processing -func (s *Service) saveAndProcessEvent(e *inter.EventPayload, es *iblockproc.EpochState) error { - fixEventTxHashes(e) - // indexing event - s.store.SetEvent(e) - defer s.dagIndexer.DropNotFlushed() - - err := s.processSavedEvent(e, es) - if err != nil { - s.store.DelEvent(e.ID()) - return err - } - - // save event index after success - s.dagIndexer.Flush() - return nil -} - -func processEventHeads(heads *concurrent.EventsSet, e *inter.EventPayload) *concurrent.EventsSet { - // track events with no descendants, i.e. "heads" - heads.Lock() - defer heads.Unlock() - heads.Val.Erase(e.Parents()...) - heads.Val.Add(e.ID()) - return heads -} - -func processLastEvent(lasts *concurrent.ValidatorEventsSet, e *inter.EventPayload) *concurrent.ValidatorEventsSet { - // set validator's last event. we don't care about forks, because this index is used only for emitter - lasts.Lock() - defer lasts.Unlock() - lasts.Val[e.Creator()] = e.ID() - return lasts -} - -func (s *Service) switchEpochTo(newEpoch idx.Epoch) { - s.store.cache.EventIDs.Reset(newEpoch) - s.store.SetHighestLamport(0) - // reset dag indexer - s.store.resetEpochStore(newEpoch) - es := s.store.getEpochStore(newEpoch) - s.dagIndexer.Reset(s.store.GetValidators(), es.table.DagIndex, func(id hash.Event) dag.Event { - return s.store.GetEvent(id) - }) - // notify event checkers about new validation data - s.gasPowerCheckReader.Ctx.Store(NewGasPowerContext(s.store, s.store.GetValidators(), newEpoch, s.store.GetRules().Economy)) // read gaspower check data from disk - s.heavyCheckReader.Pubkeys.Store(readEpochPubKeys(s.store, newEpoch)) - // notify about new epoch - for _, em := range s.emitters { - em.OnNewEpoch(s.store.GetValidators(), newEpoch) - } - s.feed.newEpoch.Send(newEpoch) -} - -func (s *Service) SwitchEpochTo(newEpoch idx.Epoch) error { - bs, es := s.store.GetHistoryBlockEpochState(newEpoch) - if bs == nil { - return errNonExistingEpoch - } - s.engineMu.Lock() - defer s.engineMu.Unlock() - s.blockProcWg.Wait() - if newEpoch == s.store.GetEpoch() { - return errSameEpoch - } - s.store.evm.RebuildEvmSnapshot(common.Hash(bs.FinalizedStateRoot)) - err := s.engine.Reset(newEpoch, es.Validators) - if err != nil { - return err - } - s.store.SetBlockEpochState(*bs, *es) - s.switchEpochTo(newEpoch) - s.commit(true) - return nil -} - -func (s *Service) PauseEvmSnapshot() { - s.engineMu.Lock() - defer s.engineMu.Unlock() - s.blockProcWg.Wait() - if !s.store.evm.IsEvmSnapshotPaused() { - s.store.evm.PauseEvmSnapshot() - } -} - -func (s *Service) EvmSnapshotGeneration() bool { - gen, _ := s.store.evm.Snaps.Generating() - return gen -} - -func (s *Service) processEventEpochIndex(e *inter.EventPayload, oldEpoch, newEpoch idx.Epoch) { - // index DAG heads and last events - s.store.SetHeads(oldEpoch, processEventHeads(s.store.GetHeads(oldEpoch), e)) - s.store.SetLastEvents(oldEpoch, processLastEvent(s.store.GetLastEvents(oldEpoch), e)) - // update highest Lamport - if newEpoch != oldEpoch { - s.store.SetHighestLamport(0) - } else if e.Lamport() > s.store.GetHighestLamport() { - s.store.SetHighestLamport(e.Lamport()) - } -} - -func (s *Service) ReprocessEpochEvents() { - s.bootstrapping = true - // reprocess epoch events, as epoch DBs don't survive restart - s.store.ForEachEpochEvent(s.store.GetEpoch(), func(event *inter.EventPayload) bool { - err := s.dagIndexer.Add(event) - if err != nil { - log.Crit("Failed to reindex epoch event", "event", event.String(), "err", err) - } - s.dagIndexer.Flush() - err = s.engine.Process(event) - if err != nil { - log.Crit("Failed to reprocess epoch event", "event", event.String(), "err", err) - } - s.processEventEpochIndex(event, event.Epoch(), event.Epoch()) - return true - }) - s.bootstrapping = false -} - -// processEvent extends the engine.Process with gossip-specific actions on each event processing -func (s *Service) processEvent(e *inter.EventPayload) error { - // s.engineMu is locked here - if s.stopped { - return errStopped - } - if err := s.verWatcher.Pause(); err != nil { - return err - } - if gen, err := s.store.evm.Snaps.Generating(); gen || err != nil { - // never allow fullsync while EVM snap is still generating, as it may lead to a race condition - s.Log.Warn("EVM snapshot is not ready during event processing", "gen", gen, "err", err) - return errDirtyEvmSnap - } - atomic.StoreUint32(&s.eventBusyFlag, 1) - defer atomic.StoreUint32(&s.eventBusyFlag, 0) - - // repeat the checks under the mutex which may depend on volatile data - if s.store.HasEvent(e.ID()) { - return eventcheck.ErrAlreadyConnectedEvent - } - if err := s.checkers.Epochcheck.Validate(e); err != nil { - return err - } - - oldEpoch := s.store.GetEpoch() - es := s.store.GetEpochState() - - // check prev epoch hash - if e.PrevEpochHash() != nil { - if *e.PrevEpochHash() != es.Hash() { - s.store.DelEvent(e.ID()) - return errWrongEpochHash - } - } - - // Process LLR votes - err := s.processBlockVotes(inter.AsSignedBlockVotes(e)) - if err != nil && err != eventcheck.ErrAlreadyProcessedBVs { - return err - } - err = s.processEpochVote(inter.AsSignedEpochVote(e)) - if err != nil && err != eventcheck.ErrAlreadyProcessedEV { - return err - } - - err = s.saveAndProcessEvent(e, &es) - if err != nil { - return err - } - - newEpoch := s.store.GetEpoch() - - s.processEventEpochIndex(e, oldEpoch, newEpoch) - - for _, em := range s.emitters { - em.OnEventConnected(e) - } - - if newEpoch != oldEpoch { - s.switchEpochTo(newEpoch) - } - - s.mayCommit(newEpoch != oldEpoch) - - if s.haltCheck != nil && s.haltCheck(oldEpoch, newEpoch, e.MedianTime().Time()) { - // halt syncing - s.stopped = true - } - return nil -} - -type uniqueID struct { - counter *big.Int -} - -func (u *uniqueID) sample() [24]byte { - u.counter.Add(u.counter, common.Big1) - var id [24]byte - copy(id[:], u.counter.Bytes()) - return id -} - -func (s *Service) DagProcessor() *dagprocessor.Processor { - return s.handler.dagProcessor -} - -func (s *Service) mayCommit(epochSealing bool) { - // s.engineMu is locked here - if epochSealing || s.store.IsCommitNeeded() { - s.commit(epochSealing) - } -} - -func (s *Service) commit(epochSealing bool) { - // s.engineMu is locked here - s.blockProcWg.Wait() - // if gcmode is full and snapsync is finalized, clean all the old state trie - // and commit the state trie at the current block - if !s.store.cfg.EVM.Cache.TrieDirtyDisabled && s.handler.syncStatus.AcceptEvents() { - s.store.cleanCommitEVM() - } - _ = s.store.Commit() - if epochSealing { - s.store.CaptureEvmKvdbSnapshot() - } -} diff --git a/evm/go-x1/gossip/c_llr_callbacks.go b/evm/go-x1/gossip/c_llr_callbacks.go deleted file mode 100644 index 59091c1..0000000 --- a/evm/go-x1/gossip/c_llr_callbacks.go +++ /dev/null @@ -1,293 +0,0 @@ -package gossip - -import ( - "errors" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/eventcheck" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/opera" -) - -var errValidatorNotExist = errors.New("validator does not exist") - -func actualizeLowestIndex(current, upd uint64, exists func(uint64) bool) uint64 { - if current == upd { - current++ - for exists(current) { - current++ - } - } - return current -} - -func (s *Service) processBlockVote(block idx.Block, epoch idx.Epoch, bv hash.Hash, val idx.Validator, vals *pos.Validators, llrs *LlrState) { - newWeight := s.store.AddLlrBlockVoteWeight(block, epoch, bv, val, vals.Len(), vals.GetWeightByIdx(val)) - if newWeight >= vals.TotalWeight()/3+1 { - wonBr := s.store.GetLlrBlockResult(block) - if wonBr == nil { - s.store.SetLlrBlockResult(block, bv) - llrs.LowestBlockToDecide = idx.Block(actualizeLowestIndex(uint64(llrs.LowestBlockToDecide), uint64(block), func(u uint64) bool { - return s.store.GetLlrBlockResult(idx.Block(u)) != nil - })) - } else if *wonBr != bv { - s.Log.Error("LLR voting doublesign is met", "block", block) - } - } -} - -func (s *Service) processBlockVotes(bvs inter.LlrSignedBlockVotes) error { - // engineMu should be locked here - if len(bvs.Val.Votes) == 0 { - // short circuit if no records - return nil - } - if s.store.HasBlockVotes(bvs.Val.Epoch, bvs.Val.LastBlock(), bvs.Signed.Locator.ID()) { - return eventcheck.ErrAlreadyProcessedBVs - } - done := s.procLogger.BlockVotesConnectionStarted(bvs) - defer done() - vid := bvs.Signed.Locator.Creator - - // get the validators group - epoch := bvs.Signed.Locator.Epoch - es := s.store.GetHistoryEpochState(epoch) - if es == nil { - return eventcheck.ErrUnknownEpochBVs - } - - if !es.Validators.Exists(vid) { - return errValidatorNotExist - } - - s.store.ModifyLlrState(func(llrs *LlrState) { - b := bvs.Val.Start - for _, bv := range bvs.Val.Votes { - s.processBlockVote(b, bvs.Val.Epoch, bv, es.Validators.GetIdx(vid), es.Validators, llrs) - b++ - } - }) - s.store.SetBlockVotes(bvs) - lBVs := s.store.GetLastBVs() - lBVs.Lock() - if bvs.Val.LastBlock() > lBVs.Val[vid] { - lBVs.Val[vid] = bvs.Val.LastBlock() - s.store.SetLastBVs(lBVs) - } - lBVs.Unlock() - - return nil -} - -func (s *Service) ProcessBlockVotes(bvs inter.LlrSignedBlockVotes) error { - s.engineMu.Lock() - defer s.engineMu.Unlock() - - err := s.processBlockVotes(bvs) - if err == nil { - s.mayCommit(false) - } - return err -} - -func indexRawReceipts(s *Store, receiptsForStorage []*types.ReceiptForStorage, txs types.Transactions, blockIdx idx.Block, atropos hash.Event) { - s.evm.SetRawReceipts(blockIdx, receiptsForStorage) - receipts, _ := evmstore.UnwrapStorageReceipts(receiptsForStorage, blockIdx, nil, common.Hash(atropos), txs) - for _, r := range receipts { - s.evm.IndexLogs(r.Logs...) - } -} - -func (s *Store) WriteFullBlockRecord(br ibr.LlrIdxFullBlockRecord) { - txHashes := make([]common.Hash, 0, len(br.Txs)) - for _, tx := range br.Txs { - txHashes = append(txHashes, tx.Hash()) - s.EvmStore().SetTx(tx.Hash(), tx) - } - - if len(br.Receipts) != 0 { - // Note: it's possible for receipts to get indexed twice by BR and block processing - indexRawReceipts(s, br.Receipts, br.Txs, br.Idx, br.Atropos) - } - for i, tx := range br.Txs { - s.EvmStore().SetTx(tx.Hash(), tx) - s.EvmStore().SetTxPosition(tx.Hash(), evmstore.TxPosition{ - Block: br.Idx, - BlockOffset: uint32(i), - }) - } - s.SetBlock(br.Idx, &inter.Block{ - Time: br.Time, - Atropos: br.Atropos, - Events: hash.Events{}, - Txs: txHashes, - InternalTxs: []common.Hash{}, - SkippedTxs: []uint32{}, - GasUsed: br.GasUsed, - Root: br.Root, - }) - s.SetBlockIndex(br.Atropos, br.Idx) -} - -func (s *Service) ProcessFullBlockRecord(br ibr.LlrIdxFullBlockRecord) error { - // engineMu should NOT be locked here - if s.store.HasBlock(br.Idx) { - return eventcheck.ErrAlreadyProcessedBR - } - done := s.procLogger.BlockRecordConnectionStarted(br) - defer done() - res := s.store.GetLlrBlockResult(br.Idx) - if res == nil { - return eventcheck.ErrUndecidedBR - } - - if br.Hash() != *res { - return errors.New("block record hash mismatch") - } - - s.store.WriteFullBlockRecord(br) - s.engineMu.Lock() - defer s.engineMu.Unlock() - if s.verWatcher != nil { - // Note: it's possible for logs to get indexed twice by BR and block processing - for _, r := range br.Receipts { - for _, l := range r.Logs { - s.verWatcher.OnNewLog(l) - } - } - } - updateLowestBlockToFill(br.Idx, s.store) - s.mayCommit(false) - - return nil -} - -func (s *Service) processRawEpochVote(epoch idx.Epoch, ev hash.Hash, val idx.Validator, vals *pos.Validators, llrs *LlrState) { - newWeight := s.store.AddLlrEpochVoteWeight(epoch, ev, val, vals.Len(), vals.GetWeightByIdx(val)) - if newWeight >= vals.TotalWeight()/3+1 { - wonEr := s.store.GetLlrEpochResult(epoch) - if wonEr == nil { - s.store.SetLlrEpochResult(epoch, ev) - llrs.LowestEpochToDecide = idx.Epoch(actualizeLowestIndex(uint64(llrs.LowestEpochToDecide), uint64(epoch), func(u uint64) bool { - return s.store.GetLlrEpochResult(idx.Epoch(u)) != nil - })) - } else if *wonEr != ev { - s.Log.Error("LLR voting doublesign is met", "epoch", epoch) - } - } -} - -func (s *Service) processEpochVote(ev inter.LlrSignedEpochVote) error { - // engineMu should be locked here - if ev.Val.Epoch == 0 { - // short circuit if no records - return nil - } - if s.store.HasEpochVote(ev.Val.Epoch, ev.Signed.Locator.ID()) { - return eventcheck.ErrAlreadyProcessedEV - } - done := s.procLogger.EpochVoteConnectionStarted(ev) - defer done() - vid := ev.Signed.Locator.Creator - - // get the validators group - es := s.store.GetHistoryEpochState(ev.Val.Epoch - 1) - if es == nil { - return eventcheck.ErrUnknownEpochEV - } - - if !es.Validators.Exists(vid) { - return errValidatorNotExist - } - - s.store.ModifyLlrState(func(llrs *LlrState) { - s.processRawEpochVote(ev.Val.Epoch, ev.Val.Vote, es.Validators.GetIdx(vid), es.Validators, llrs) - }) - s.store.SetEpochVote(ev) - lEVs := s.store.GetLastEVs() - lEVs.Lock() - if ev.Val.Epoch > lEVs.Val[vid] { - lEVs.Val[vid] = ev.Val.Epoch - s.store.SetLastEVs(lEVs) - } - lEVs.Unlock() - - return nil -} - -func (s *Service) ProcessEpochVote(ev inter.LlrSignedEpochVote) error { - s.engineMu.Lock() - defer s.engineMu.Unlock() - - err := s.processEpochVote(ev) - if err == nil { - s.mayCommit(false) - } - return err -} - -func (s *Store) WriteFullEpochRecord(er ier.LlrIdxFullEpochRecord) { - s.SetHistoryBlockEpochState(er.Idx, er.BlockState, er.EpochState) - s.SetEpochBlock(er.BlockState.LastBlock.Idx+1, er.Idx) -} - -func (s *Store) WriteUpgradeHeight(bs iblockproc.BlockState, es iblockproc.EpochState, prevEs *iblockproc.EpochState) { - if prevEs == nil || es.Rules.Upgrades != prevEs.Rules.Upgrades { - s.AddUpgradeHeight(opera.UpgradeHeight{ - Upgrades: es.Rules.Upgrades, - Height: bs.LastBlock.Idx + 1, - }) - } -} - -func (s *Service) ProcessFullEpochRecord(er ier.LlrIdxFullEpochRecord) error { - // engineMu should NOT be locked here - if s.store.HasHistoryBlockEpochState(er.Idx) { - return eventcheck.ErrAlreadyProcessedER - } - done := s.procLogger.EpochRecordConnectionStarted(er) - defer done() - - res := s.store.GetLlrEpochResult(er.Idx) - if res == nil { - return eventcheck.ErrUndecidedER - } - - if er.Hash() != *res { - return errors.New("epoch record hash mismatch") - } - - s.store.WriteFullEpochRecord(er) - s.store.WriteUpgradeHeight(er.BlockState, er.EpochState, s.store.GetHistoryEpochState(er.EpochState.Epoch-1)) - s.engineMu.Lock() - defer s.engineMu.Unlock() - updateLowestEpochToFill(er.Idx, s.store) - s.mayCommit(false) - - return nil -} - -func updateLowestBlockToFill(block idx.Block, store *Store) { - store.ModifyLlrState(func(llrs *LlrState) { - llrs.LowestBlockToFill = idx.Block(actualizeLowestIndex(uint64(llrs.LowestBlockToFill), uint64(block), func(u uint64) bool { - return store.GetBlock(idx.Block(u)) != nil - })) - }) -} - -func updateLowestEpochToFill(epoch idx.Epoch, store *Store) { - store.ModifyLlrState(func(llrs *LlrState) { - llrs.LowestEpochToFill = idx.Epoch(actualizeLowestIndex(uint64(llrs.LowestEpochToFill), uint64(epoch), func(u uint64) bool { - return store.HasHistoryBlockEpochState(idx.Epoch(u)) - })) - }) -} diff --git a/evm/go-x1/gossip/c_llr_callbacks_test.go b/evm/go-x1/gossip/c_llr_callbacks_test.go deleted file mode 100644 index 2e0d05f..0000000 --- a/evm/go-x1/gossip/c_llr_callbacks_test.go +++ /dev/null @@ -1,1702 +0,0 @@ -package gossip - -import ( - "context" - "errors" - "fmt" - "math/big" - "math/rand" - "reflect" - "sync" - "testing" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc" - "github.com/status-im/keycard-go/hexutils" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - "github.com/Fantom-foundation/go-opera/eventcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/epochcheck" - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/contract/ballot" - "github.com/Fantom-foundation/go-opera/gossip/filters" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" -) - -type IntegrationTestSuite struct { - suite.Suite - - startEpoch, lastEpoch idx.Epoch - generator, processor *testEnv - epochToEvsMap map[idx.Epoch][]*inter.LlrSignedEpochVote - bvs []*inter.LlrSignedBlockVotes - blockIndices []idx.Block -} - -func (s *IntegrationTestSuite) SetupTest() { - const ( - rounds = 20 - validatorsNum = 10 - startEpoch = 1 - ) - - //creating generator and processor - generator := newTestEnv(startEpoch, validatorsNum) - processor := newTestEnv(startEpoch, validatorsNum) - - proposals := [][32]byte{ - ballotOption("Option 1"), - ballotOption("Option 2"), - ballotOption("Option 3"), - } - - for n := uint64(0); n < rounds; n++ { - txs := make([]*types.Transaction, validatorsNum) - for i := idx.Validator(0); i < validatorsNum; i++ { - _, tx, cBallot, err := ballot.DeployBallot(generator.Pay(idx.ValidatorID(i+1)), generator, proposals) - s.Require().NoError(err) - s.Require().NotNil(cBallot) - s.Require().NotNil(tx) - txs[i] = tx - } - tm := sameEpoch - if n%10 == 0 { - tm = nextEpoch - } - - rr, err := generator.ApplyTxs(tm, txs...) - s.Require().NoError(err) - for _, r := range rr { - s.Require().Len(r.Logs, 3) - for _, l := range r.Logs { - s.Require().NotNil(l) - } - } - } - - s.startEpoch = startEpoch - s.generator = generator - s.processor = processor - - s.epochToEvsMap = fetchEvs(s.generator) - bvs, blockIndices := fetchBvsBlockIdxs(s.generator) - s.bvs = bvs - s.blockIndices = blockIndices - s.lastEpoch = generator.store.GetEpoch() -} - -func (s *IntegrationTestSuite) TearDownSuite() { - s.T().Log("tearing down test suite") - s.generator.Close() - s.processor.Close() -} - -// fetchEvs fetches LlrSignedEpochVotes from generator -func fetchEvs(generator *testEnv) map[idx.Epoch][]*inter.LlrSignedEpochVote { - m := make(map[idx.Epoch][]*inter.LlrSignedEpochVote) - it := generator.store.table.LlrEpochVotes.NewIterator(nil, nil) - defer it.Release() - for it.Next() { - ev := &inter.LlrSignedEpochVote{} - if err := rlp.DecodeBytes(it.Value(), ev); err != nil { - generator.store.Log.Crit("Failed to decode epoch vote", "err", err) - } - - if ev != nil { - m[ev.Val.Epoch] = append(m[ev.Val.Epoch], ev) - } - } - return m -} - -// fetchBvsBlockIdxs fetches block indices of blocks that have min 4 LLR votes. -func fetchBvsBlockIdxs(generator *testEnv) ([]*inter.LlrSignedBlockVotes, []idx.Block) { - var bvs []*inter.LlrSignedBlockVotes - blockIdxCountMap := make(map[idx.Block]uint64) - - // fetching blockIndices with at least minVoteCount - fetchBlockIdxs := func(blockIdxCountMap map[idx.Block]uint64) (blockIndices []idx.Block) { - const minVoteCount = 4 - for blockIdx, count := range blockIdxCountMap { - if count >= minVoteCount { - blockIndices = append(blockIndices, blockIdx) - } - } - return - } - - // compute how any votes have been given for a particular block idx - fillblockIdxCountMap := func(bv *inter.LlrSignedBlockVotes) { - start, end := bv.Val.Start, bv.Val.Start+idx.Block(len(bv.Val.Votes))-1 - - for b := start; start != 0 && b <= end; b++ { - blockIdxCountMap[b] += 1 - } - } - - it := generator.store.table.LlrBlockVotes.NewIterator(nil, nil) - defer it.Release() - for it.Next() { - bv := &inter.LlrSignedBlockVotes{} - if err := rlp.DecodeBytes(it.Value(), bv); err != nil { - generator.store.Log.Crit("Failed to decode block vote while running ", "err", err) - } - - if bv != nil { - fillblockIdxCountMap(bv) - bvs = append(bvs, bv) - } - } - - return bvs, fetchBlockIdxs(blockIdxCountMap) -} - -// txByBlockSubsetOf iterates over procMap keys and checks equality of transaction hashes of genenerator and processor -func txByBlockSubsetOf(t *testing.T, procMap, genMap map[idx.Block]types.Transactions) { - // assert len(procBlockToTxsMap.keys()) <= len(genBlockToTxsMap.keys()") - require.LessOrEqual(t, len(reflect.ValueOf(procMap).MapKeys()), len(reflect.ValueOf(genMap).MapKeys()), "The number of keys does not match") - for b, txs := range procMap { - genTxs, ok := genMap[b] - require.True(t, ok) - require.Equal(t, len(txs), len(genTxs)) - for i, tx := range txs { - require.Equal(t, tx.Hash().Hex(), genTxs[i].Hash().Hex()) - } - } -} - -// checkLogsEquality checks equality of logs slice field byf ield -func checkLogsEquality(t *testing.T, genLogs, procLogs []*types.Log) { - require.Equal(t, len(genLogs), len(procLogs)) - for i, procLog := range procLogs { - // compare all fields - require.Equal(t, procLog.Address.Hex(), genLogs[i].Address.Hex()) - require.Equal(t, procLog.BlockHash.Hex(), genLogs[i].BlockHash.Hex()) - require.Equal(t, procLog.BlockNumber, genLogs[i].BlockNumber) - require.Equal(t, hexutils.BytesToHex(procLog.Data), hexutils.BytesToHex(genLogs[i].Data)) - require.Equal(t, procLog.Index, genLogs[i].Index) - require.Equal(t, procLog.Removed, genLogs[i].Removed) - - for j, topic := range procLog.Topics { - require.Equal(t, topic.Hex(), genLogs[i].Topics[j].Hex()) - } - - require.Equal(t, procLog.TxHash.Hex(), genLogs[i].TxHash.Hex()) - require.Equal(t, procLog.TxIndex, genLogs[i].TxIndex) - } -} - -type testParams struct { - t *testing.T - genEvmBlock *evmcore.EvmBlock - procEvmBlock *evmcore.EvmBlock - genReceipts types.Receipts - procReceipts types.Receipts -} - -func newTestParams(t *testing.T, genEvmBlock, procEvmBlock *evmcore.EvmBlock, genReceipts, procReceipts types.Receipts) testParams { - return testParams{t, genEvmBlock, procEvmBlock, genReceipts, procReceipts} -} - -func (p testParams) compareEvmBlocks() { - // comparing all fields of genEvmBlock and procEvmBlock - require.Equal(p.t, p.genEvmBlock.Number, p.procEvmBlock.Number) - require.Equal(p.t, p.genEvmBlock.Hash, p.procEvmBlock.Hash) - require.Equal(p.t, p.genEvmBlock.ParentHash, p.procEvmBlock.ParentHash) - require.Equal(p.t, p.genEvmBlock.Root, p.procEvmBlock.Root) - require.Equal(p.t, p.genEvmBlock.TxHash, p.procEvmBlock.TxHash) - require.Equal(p.t, p.genEvmBlock.Time, p.procEvmBlock.Time) - require.Equal(p.t, p.genEvmBlock.GasLimit, p.procEvmBlock.GasLimit) - require.Equal(p.t, p.genEvmBlock.GasUsed, p.procEvmBlock.GasUsed) - require.Equal(p.t, p.genEvmBlock.BaseFee, p.procEvmBlock.BaseFee) -} - -func (p testParams) compareReceipts() { - require.Equal(p.t, len(p.genReceipts), len(p.procReceipts)) - // compare every field except logs, I compare them separately - for i, initRec := range p.genReceipts { - require.Equal(p.t, initRec.Type, p.procReceipts[i].Type) - require.Equal(p.t, hexutils.BytesToHex(initRec.PostState), hexutils.BytesToHex(p.procReceipts[i].PostState)) - require.Equal(p.t, initRec.Status, p.procReceipts[i].Status) - require.Equal(p.t, initRec.CumulativeGasUsed, p.procReceipts[i].CumulativeGasUsed) - require.Equal(p.t, hexutils.BytesToHex(initRec.Bloom.Bytes()), hexutils.BytesToHex(p.procReceipts[i].Bloom.Bytes())) - require.Equal(p.t, initRec.TxHash.Hex(), p.procReceipts[i].TxHash.Hex()) - require.Equal(p.t, initRec.ContractAddress.Hex(), p.procReceipts[i].ContractAddress.Hex()) - require.Equal(p.t, initRec.GasUsed, p.procReceipts[i].GasUsed) - require.Equal(p.t, initRec.BlockHash.String(), p.procReceipts[i].BlockHash.String()) - require.Equal(p.t, initRec.BlockNumber, p.procReceipts[i].BlockNumber) - require.Equal(p.t, initRec.TransactionIndex, p.procReceipts[i].TransactionIndex) - } -} - -func (p testParams) compareLogs(initLogs2D, procLogs2D [][]*types.Log) { - require.Equal(p.t, len(initLogs2D), len(procLogs2D)) - for i, initLogs := range initLogs2D { - checkLogsEquality(p.t, initLogs, procLogs2D[i]) - } -} - -func (p testParams) serializeAndCompare(val1, val2 interface{}) { - // serialize val1 and val2 - buf1, err := rlp.EncodeToBytes(val1) - require.NotNil(p.t, buf1) - require.NoError(p.t, err) - buf2, err := rlp.EncodeToBytes(val2) - require.NotNil(p.t, buf2) - require.NoError(p.t, err) - - // compare serialized representation of val1 and val2 - require.Equal(p.t, hexutils.BytesToHex(buf1), hexutils.BytesToHex(buf2)) -} - -func (p testParams) compareTransactions(initiator, processor *testEnv) { - ctx := context.Background() - require.Equal(p.t, len(p.genEvmBlock.Transactions), len(p.procEvmBlock.Transactions)) - for i, tx := range p.genEvmBlock.Transactions { - txHash := tx.Hash() - initTx, _, _, err := initiator.EthAPI.GetTransaction(ctx, txHash) - require.NoError(p.t, err) - - procTx, _, _, err := processor.EthAPI.GetTransaction(ctx, txHash) - require.NoError(p.t, err) - - require.Equal(p.t, txHash.Hex(), p.procEvmBlock.Transactions[i].Hash().Hex()) - require.Equal(p.t, txHash.Hex(), initTx.Hash().Hex()) - require.Equal(p.t, txHash.Hex(), procTx.Hash().Hex()) - } -} - -func fetchTxsbyBlock(env *testEnv) map[idx.Block]types.Transactions { - m := make(map[idx.Block]types.Transactions) - it := env.store.table.Blocks.NewIterator(nil, nil) - defer it.Release() - for it.Next() { - block := &inter.Block{} - if err := rlp.DecodeBytes(it.Value(), block); err != nil { - env.store.Log.Crit("Failed to decode block", "err", err) - } - - if block != nil { - n := idx.BytesToBlock(it.Key()) - txs := env.store.GetBlockTxs(n, block) - m[n] = txs - } - } - return m -} - -type repeater struct { - generator *testEnv - processor *testEnv - bvs []*inter.LlrSignedBlockVotes - blockIndices []idx.Block - epochToEvsMap map[idx.Epoch][]*inter.LlrSignedEpochVote - t *testing.T -} - -func newRepeater(s *IntegrationTestSuite) repeater { - return repeater{ - generator: s.generator, - processor: s.processor, - bvs: s.bvs, - blockIndices: s.blockIndices, - epochToEvsMap: s.epochToEvsMap, - t: s.T(), - } -} - -// processBlockVotesRecords processes block votes. Moreover, it processes block records for every block index that has minimum 4 LLr Votes. -// If ProcessFullBlockRecord returns an error, omit it in fullRepeater scenario, but not in testRepeater scenario. -func (r repeater) processBlockVotesRecords(isTestRepeater bool) { - for _, bv := range r.bvs { - r.processor.ProcessBlockVotes(*bv) - } - - for _, blockIdx := range r.blockIndices { - if br := r.generator.store.GetFullBlockRecord(blockIdx); br != nil { - ibr := ibr.LlrIdxFullBlockRecord{LlrFullBlockRecord: *br, Idx: blockIdx} - err := r.processor.ProcessFullBlockRecord(ibr) - if err == nil { - continue - } - - // do not ingore this error in testRepeater - if isTestRepeater { - require.NoError(r.t, err) - } else { - // omit this error in fullRepeater - require.EqualError(r.t, err, eventcheck.ErrAlreadyProcessedBR.Error()) - } - - } else { - r.generator.Log.Crit("Empty full block record popped up") - } - } -} - -// processEpochVotesRecords processes each epoch vote. Additionally, it processes epoch block records in range [startEpoch+1; lastEpoch] -func (r repeater) processEpochVotesRecords(startEpoch, lastEpoch idx.Epoch) { - // invoke repeater.ProcessEpochVote and ProcessFullEpochRecord for epoch in range [2; lastepoch] - for e := idx.Epoch(startEpoch + 1); e <= lastEpoch; e++ { - epochVotes, ok := r.epochToEvsMap[e] - if !ok { - r.processor.store.Log.Crit("Failed to fetch epoch votes for a given epoch") - } - - for _, v := range epochVotes { - require.NoError(r.t, r.processor.ProcessEpochVote(*v)) - } - - if er := r.generator.store.GetFullEpochRecord(e); er != nil { - ier := ier.LlrIdxFullEpochRecord{LlrFullEpochRecord: *er, Idx: e} - require.NoError(r.t, r.processor.ProcessFullEpochRecord(ier)) - } - } -} - -// compareERHashes compares epoch recors hashes. Moreover, it checks equality of hashes of epoch and block states. -func (r repeater) compareERHashes(startEpoch, lastEpoch idx.Epoch) { - for e := startEpoch; e <= lastEpoch; e++ { - - genBs, genEs := r.generator.store.GetHistoryBlockEpochState(e) - repBs, repEs := r.processor.store.GetHistoryBlockEpochState(e) - require.Equal(r.t, genBs.Hash().Hex(), repBs.Hash().Hex()) - require.Equal(r.t, genEs.Hash().Hex(), repEs.Hash().Hex()) - - genEr := r.generator.store.GetFullEpochRecord(e) - repEr := r.processor.store.GetFullEpochRecord(e) - require.Equal(r.t, genEr.Hash().Hex(), repEr.Hash().Hex()) - } -} - -// compareParams checks equality of different parameters such as BlockByHash, BlockByNumber, Receipts, Logs -func (r repeater) compareParams() { - ctx := context.Background() - - // compare blockbyNumber - for _, blockIdx := range r.blockIndices { - - // comparing EvmBlock by calling BlockByHash - genEvmBlock, err := r.generator.EthAPI.BlockByNumber(ctx, rpc.BlockNumber(blockIdx)) - require.NotNil(r.t, genEvmBlock) - require.NoError(r.t, err) - - procEvmBlock, err := r.processor.EthAPI.BlockByNumber(ctx, rpc.BlockNumber(blockIdx)) - require.NotNil(r.t, procEvmBlock) - require.NoError(r.t, err) - - // compare Receipts - genReceipts := r.generator.store.evm.GetReceipts(blockIdx, r.generator.EthAPI.signer, genEvmBlock.Hash, genEvmBlock.Transactions) - require.NotNil(r.t, genReceipts) - procReceipts := r.processor.store.evm.GetReceipts(blockIdx, r.processor.EthAPI.signer, procEvmBlock.Hash, procEvmBlock.Transactions) - require.NotNil(r.t, procReceipts) - - testParams := newTestParams(r.t, genEvmBlock, procEvmBlock, genReceipts, procReceipts) - testParams.compareEvmBlocks() - - r.t.Log("comparing receipts") - testParams.compareReceipts() - - // comparing evmBlock by calling BlockByHash - genEvmBlock, err = r.generator.EthAPI.BlockByHash(ctx, genEvmBlock.Hash) - require.NotNil(r.t, genEvmBlock) - require.NoError(r.t, err) - procEvmBlock, err = r.processor.EthAPI.BlockByHash(ctx, procEvmBlock.Hash) - require.NotNil(r.t, procEvmBlock) - require.NoError(r.t, err) - - testParams = newTestParams(r.t, genEvmBlock, procEvmBlock, genReceipts, procReceipts) - testParams.compareEvmBlocks() - - // compare Logs - genLogs, err := r.generator.EthAPI.GetLogs(ctx, genEvmBlock.Hash) - require.NoError(r.t, err) - - procLogs, err := r.processor.EthAPI.GetLogs(ctx, genEvmBlock.Hash) - require.NoError(r.t, err) - - r.t.Log("comparing logs") - testParams.serializeAndCompare(genLogs, procLogs) - testParams.compareLogs(genLogs, procLogs) - - // compare ReceiptForStorage - genBR := r.generator.store.GetFullBlockRecord(blockIdx) - procBR := r.processor.store.GetFullBlockRecord(blockIdx) - testParams.serializeAndCompare(genBR.Receipts, procBR.Receipts) - - // compare BR hashes - require.Equal(r.t, genBR.Hash().Hex(), procBR.Hash().Hex()) - - // compare transactions - testParams.compareTransactions(r.generator, r.processor) - } -} - -// compareLogsByFilterCriteria introduces testing logic for GetLogs function for generator and processor -func (r repeater) compareLogsByFilterCriteria() { - var crit filters.FilterCriteria - - blockIdxLogsMap := func() map[idx.Block][]*types.Log { - ctx := context.Background() - m := make(map[idx.Block][]*types.Log, len(r.blockIndices)) - - for _, blockIdx := range r.blockIndices { - block, err := r.generator.EthAPI.BlockByNumber(ctx, rpc.BlockNumber(blockIdx)) - require.NotNil(r.t, block) - require.NoError(r.t, err) - receipts := r.generator.store.evm.GetReceipts(blockIdx, r.generator.EthAPI.signer, block.Hash, block.Transactions) - for _, r := range receipts { - // we add only non empty logs - if len(r.Logs) > 0 { - m[blockIdx] = append(m[blockIdx], r.Logs...) - } - } - - } - return m - }() - - findLastNonEmptyLogs := func() (idx.Block, []*types.Log, error) { - for i := len(r.blockIndices) - 1; i >= 0; i-- { - logs, ok := blockIdxLogsMap[r.blockIndices[i]] - if !ok { - continue - } - if len(logs) > 0 { - return r.blockIndices[i], logs, nil - } - } - - return 0, nil, errors.New("all blocks have no logs") - } - - lastBlockNumber, lastLogs, err := findLastNonEmptyLogs() - require.NoError(r.t, err) - require.NotNil(r.t, lastLogs) - - defaultCrit := filters.FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(int64(lastBlockNumber/2 + 1))} - - ctx := context.Background() - - config := filters.DefaultConfig() - config.UnindexedLogsBlockRangeLimit = idx.Block(1000) - genApi := filters.NewPublicFilterAPI(r.generator.EthAPI, config) - require.NotNil(r.t, genApi) - - procApi := filters.NewPublicFilterAPI(r.processor.EthAPI, config) - require.NotNil(r.t, procApi) - - defaultLogs, err := genApi.GetLogs(ctx, defaultCrit) - require.NoError(r.t, err) - require.NotNil(r.t, defaultLogs) - require.NotEqual(r.t, defaultLogs, []*types.Log{}) - - findFirstNonEmptyLogs := func() (idx.Block, []*types.Log, error) { - for _, blockIdx := range r.blockIndices { - logs, ok := blockIdxLogsMap[blockIdx] - if !ok { - continue - } - if len(logs) > 0 { - return blockIdx, logs, nil - } - } - - return 0, nil, errors.New("all blocks have no logs") - } - - fetchFirstAddrFromLogs := func(logs []*types.Log) (common.Address, error) { - for i := range logs { - if logs[i] != nil && logs[i].Address != (common.Address{}) { - return logs[i].Address, nil - } - } - - return common.Address{}, errors.New("no address can be found in logs") - } - - fetchFirstTopicFromLogs := func(logs []*types.Log) (common.Hash, error) { - for i := range logs { - if logs[i] != nil && logs[i].Topics[0] != (common.Hash{}) { - return logs[i].Topics[0], nil - } - } - return common.Hash{}, errors.New("no topic can be found in logs") - } - - fetchRandomTopicFromLogs := func(logs []*types.Log) common.Hash { - rand.Seed(time.Now().Unix()) - l := rand.Int() % len(logs) // pick log at random - - rand.Seed(time.Now().Unix()) - t := rand.Int() % len(logs[l].Topics) // pick topic at random - - return logs[l].Topics[t] - } - - fetchRandomAddrFromLogs := func(logs []*types.Log) common.Address { - rand.Seed(time.Now().Unix()) - l := rand.Int() % len(logs) // pick log at random - - return logs[l].Address - } - - blockNumber, logs, err := findFirstNonEmptyLogs() - require.NoError(r.t, err) - require.NotNil(r.t, logs) - - firstAddr, err := fetchFirstAddrFromLogs(logs) - require.NoError(r.t, err) - - firstTopic, err := fetchFirstTopicFromLogs(logs) - require.NoError(r.t, err) - - lastAddr, err := fetchFirstAddrFromLogs(lastLogs) - require.NoError(r.t, err) - - lastTopic, err := fetchFirstTopicFromLogs(lastLogs) - require.NoError(r.t, err) - - testCases := []struct { - name string - pretest func() - success bool - }{ - {"single valid address", - func() { - crit = filters.FilterCriteria{ - FromBlock: big.NewInt(int64(blockNumber)), - ToBlock: big.NewInt(int64(blockNumber)), - Addresses: []common.Address{firstAddr}, - } - }, - true, - }, - {"single invalid address", - func() { - invalidAddr := common.BytesToAddress([]byte("invalid address")) - crit = filters.FilterCriteria{ - FromBlock: big.NewInt(int64(blockNumber)), - ToBlock: big.NewInt(int64(blockNumber)), - Addresses: []common.Address{invalidAddr}, - } - }, - false, - }, - {"invalid block range", - func() { - crit = filters.FilterCriteria{ - FromBlock: big.NewInt(int64(blockNumber) + 1), - ToBlock: big.NewInt(int64(blockNumber) + 2), - Addresses: []common.Address{firstAddr}, - } - }, - false, - }, - {"block range 1-1000", - func() { - crit = defaultCrit - }, - true, - }, - {"block range 1-1000 and first topic", - func() { - crit = defaultCrit - crit.Topics = [][]common.Hash{{firstTopic}} - }, - true, - }, - {"block range 1-1000 and random topic", - func() { - randomTopic := fetchRandomTopicFromLogs(defaultLogs) - crit = defaultCrit - crit.Topics = [][]common.Hash{{randomTopic}} - }, - true, - }, - {"block range 1-1000 and first address", - func() { - crit = defaultCrit - crit.Addresses = []common.Address{firstAddr} - }, - true, - }, - {"block range 1-1000 and random address", - func() { - randomAddress := fetchRandomAddrFromLogs(defaultLogs) - crit = defaultCrit - crit.Addresses = []common.Address{randomAddress} - }, - true, - }, - {"block range 1 to lastBlockNumber", - func() { - crit = filters.FilterCriteria{ - FromBlock: big.NewInt(int64(1)), - ToBlock: big.NewInt(int64(lastBlockNumber)), - } - }, - true, - }, - {"block range 1 to lastBlockNumber and last topic", - func() { - crit = filters.FilterCriteria{ - FromBlock: big.NewInt(int64(1)), - ToBlock: big.NewInt(int64(lastBlockNumber)), - Topics: [][]common.Hash{{lastTopic}}, - } - }, - true, - }, - {"block range 1 to lastBlockNumber, last address", - func() { - crit = filters.FilterCriteria{ - FromBlock: big.NewInt(int64(1)), - ToBlock: big.NewInt(int64(lastBlockNumber)), - Addresses: []common.Address{lastAddr}, - } - }, - true, - }, - - {"block range is nil and last address", - func() { - crit = filters.FilterCriteria{ - Addresses: []common.Address{lastAddr}, - } - }, - true, - }, - {"block range is nil and invalid address", - func() { - invalidAddr := common.BytesToAddress([]byte("invalid addr")) - crit = filters.FilterCriteria{ - Addresses: []common.Address{invalidAddr}, - } - }, - false, - }, - } - - for _, tc := range testCases { - tc := tc - r.t.Run(tc.name, func(t *testing.T) { - tc.pretest() - genLogs, genErr := genApi.GetLogs(ctx, crit) - procLogs, procErr := procApi.GetLogs(ctx, crit) - if tc.success { - require.NoError(t, procErr) - require.NoError(t, genErr) - checkLogsEquality(t, genLogs, procLogs) - } else { - require.Equal(t, genLogs, []*types.Log{}) - require.Equal(t, procLogs, []*types.Log{}) - } - }) - } - - // iterative tests with random address and random topic - itTestCases := []struct { - name string - rounds int - pretest func() - }{ - {"block range 1-1000 and random topic", - 100, - func() { - randomTopic := fetchRandomTopicFromLogs(defaultLogs) - crit = defaultCrit - crit.Topics = [][]common.Hash{{randomTopic}} - }, - }, - {"block range 1-1000 and random address", - 100, - func() { - randomAddress := fetchRandomAddrFromLogs(defaultLogs) - crit = defaultCrit - crit.Addresses = []common.Address{randomAddress} - }, - }, - } - - for _, tc := range itTestCases { - tc := tc - r.t.Run(tc.name, func(t *testing.T) { - for i := 0; i < tc.rounds; i++ { - tc.pretest() - genLogs, genErr := genApi.GetLogs(ctx, crit) - procLogs, procErr := procApi.GetLogs(ctx, crit) - require.NoError(t, procErr) - require.NoError(t, genErr) - checkLogsEquality(t, genLogs, procLogs) - } - }) - } -} - -// use command `go test -timeout 120s -run ^TestIntegrationTestSuite$ -testify.m TestRepeater` to run test scenario -func (s *IntegrationTestSuite) TestRepeater() { - repeater := newRepeater(s) - repeater.processEpochVotesRecords(s.startEpoch, s.lastEpoch) - repeater.processBlockVotesRecords(true) - - s.Require().NoError(s.generator.store.Commit()) - s.Require().NoError(s.processor.store.Commit()) - - // Compare transaction hashes - s.T().Log("Checking procBlockToTxsMap <= genBlockToTxsMap") - genBlockToTxsMap := fetchTxsbyBlock(s.generator) - procBlockToTxsMap := fetchTxsbyBlock(s.processor) - txByBlockSubsetOf(s.T(), procBlockToTxsMap, genBlockToTxsMap) - - // compare ER hashes - repeater.compareERHashes(s.startEpoch+1, s.lastEpoch) - // compare different parameters such as Logs,Receipts, Blockhash etc - repeater.compareParams() - - // compare Logs by different criteria - repeater.compareLogsByFilterCriteria() -} - -// use command `go test -timeout 120s -run ^TestIntegrationTestSuite$ -testify.m TestFullRepeater` to run test scenario -func (s *IntegrationTestSuite) TestFullRepeater() { - - fullRepeater := newRepeater(s) - - wg := new(sync.WaitGroup) - wg.Add(2) - go func() { - defer wg.Done() - // process LLR epochVotes in fullRepeater - fullRepeater.processEpochVotesRecords(s.startEpoch, s.lastEpoch) - - // process LLR block votes and BRs in fullReapeter - fullRepeater.processBlockVotesRecords(false) - - }() - - go func() { - defer wg.Done() - events := func() (events []*inter.EventPayload) { - it := s.generator.store.table.Events.NewIterator(nil, nil) - defer it.Release() - for it.Next() { - e := &inter.EventPayload{} - if err := rlp.DecodeBytes(it.Value(), e); err != nil { - s.generator.store.Log.Crit("Failed to decode event", "err", err) - } - if e != nil { - events = append(events, e) - } - } - return - }() - - for _, e := range events { - s.processor.engineMu.Lock() - s.Require().NoError(s.processor.processEvent(e)) - s.processor.engineMu.Unlock() - } - }() - - wg.Wait() - - // Comparing the store states - fetchTable := func(table kvdb.Store) map[string]string { - var m = make(map[string]string) - it := table.NewIterator(nil, nil) - defer it.Release() - for it.Next() { - key, value := it.Key(), it.Value() - m[string(key)] = string(value) - } - return m - } - - s.Require().NoError(s.generator.store.Commit()) - s.Require().NoError(s.processor.store.Commit()) - - // Comparing generator and fullRepeater states - - // 1.Comparing Tx hashes - s.T().Log("Checking genBlockToTxsMap <= procRepBlockToTxsMap") - genBlockToTxsMap := fetchTxsbyBlock(s.generator) - procBlockToTxsMap := fetchTxsbyBlock(s.processor) - txByBlockSubsetOf(s.T(), procBlockToTxsMap, genBlockToTxsMap) - - // 2.Compare BlockByNumber,BlockByhash, GetReceipts, GetLogs - fullRepeater.compareParams() - - // 2. Comparing mainDb of generator and fullRepeater - genKVDB, _ := s.generator.store.dbs.OpenDB("gossip") - fullRepKVDB, _ := s.processor.store.dbs.OpenDB("gossip") - genKVMap := fetchTable(genKVDB) - fullRepKVMap := fetchTable(fullRepKVDB) - - subsetOf := func(aa, bb map[string]string) { - for _k, _v := range aa { - k, v := []byte(_k), []byte(_v) - if k[0] == 0 || k[0] == 'x' || k[0] == 'X' || k[0] == 'b' || k[0] == 'S' { - continue - } - s.Require().Equal(hexutils.BytesToHex(v), hexutils.BytesToHex([]byte(bb[_k]))) - } - } - - checkEqual := func(aa, bb map[string]string) { - subsetOf(aa, bb) - subsetOf(bb, aa) - } - - s.T().Log("Checking genKVs == fullKVs") - checkEqual(genKVMap, fullRepKVMap) - - genKVMapAfterIndexLogsDB, _ := s.generator.store.dbs.OpenDB("gossip") - fullRepKVMapAfterIndexLogsDB, _ := s.processor.store.dbs.OpenDB("gossip") - genKVMapAfterIndexLogs := fetchTable(genKVMapAfterIndexLogsDB) - fullRepKVMapAfterIndexLogs := fetchTable(fullRepKVMapAfterIndexLogsDB) - - // comparing the states - checkEqual(genKVMap, genKVMapAfterIndexLogs) - checkEqual(fullRepKVMap, fullRepKVMapAfterIndexLogs) - checkEqual(genKVMapAfterIndexLogs, fullRepKVMapAfterIndexLogs) - - fullRepeater.compareLogsByFilterCriteria() -} - -func TestLlrIntegrationTestSuite(t *testing.T) { - t.Skip() // skip until fixed - suite.Run(t, new(IntegrationTestSuite)) -} - -func TestBlockAndEpochRecords(t *testing.T) { - t.Skip() // skip until fixed - const ( - validatorsNum = 10 - startEpoch = 1 - ) - // setup testEnv - env := newTestEnv(startEpoch, validatorsNum) - - // 1.create epoch record er1 manually - er1 := ier.LlrIdxFullEpochRecord{Idx: idx.Epoch(startEpoch) + 1} - er1Hash := er1.Hash() - // 3. process ER1, the error will be popped up. - require.EqualError(t, env.ProcessFullEpochRecord(er1), eventcheck.ErrUndecidedER.Error()) - - // 2.create block record manually - br1 := ibr.LlrIdxFullBlockRecord{Idx: idx.Block(2)} - br1Hash := br1.Hash() - //3. process BR1, the error will popped up - require.EqualError(t, env.ProcessFullBlockRecord(br1), eventcheck.ErrUndecidedBR.Error()) - - // 4.create less than 1/3W+1 epoch votes, ER1 still should not be processed - for i := 1; i < 4; i++ { - e := fakeEvent(0, 0, true, 2, i, er1Hash) - ev := inter.AsSignedEpochVote(e) - require.NoError(t, env.ProcessEpochVote(ev)) - } - require.EqualError(t, env.ProcessFullEpochRecord(er1), eventcheck.ErrUndecidedER.Error()) - - // 5. add one more epoch vote,so 4 = 1/3W+1. Hence, ER1 has to be processed. - fmt.Println("adding 4th epoch vote") - e := fakeEvent(0, 0, true, 2, 4, er1Hash) - ev := inter.AsSignedEpochVote(e) - require.NoError(t, env.ProcessEpochVote(ev)) - require.NoError(t, env.ProcessFullEpochRecord(er1)) - - // 6.create epoch record er2 of same epoch as er1, but with another name. - er2 := ier.LlrIdxFullEpochRecord{Idx: idx.Epoch(startEpoch + 1)} - // 7.Get an error that the er has been already processed. - require.EqualError(t, env.ProcessFullEpochRecord(er2), eventcheck.ErrAlreadyProcessedER.Error()) - - //8. try to process Br1 with one vote with the same epoch as er1. it will(*Validators).GetWeightByIdx(...) - e = fakeEvent(1, er1.Idx, false, 0, 0, br1Hash) - bv := inter.AsSignedBlockVotes(e) - require.EqualError(t, env.ProcessBlockVotes(bv), errValidatorNotExist.Error()) //cause there are no validators - require.EqualError(t, env.ProcessFullBlockRecord(br1), eventcheck.ErrUndecidedBR.Error()) - - //9,10. process er1 and er2. it should yield an ErrAlreadyProcessedER error - require.EqualError(t, env.ProcessFullEpochRecord(er1), eventcheck.ErrAlreadyProcessedER.Error()) - require.EqualError(t, env.ProcessFullEpochRecord(er2), eventcheck.ErrAlreadyProcessedER.Error()) - - //11 add votes < 1/3W+1 for Br1. Record still should not be processed. - fmt.Println("adding 3 votes for br1") - for i := 5; i < 8; i++ { - e := fakeEvent(1, 0, false, 0, i, br1Hash) - bv := inter.AsSignedBlockVotes(e) - require.NoError(t, env.ProcessBlockVotes(bv)) - } - require.EqualError(t, env.ProcessFullBlockRecord(br1), eventcheck.ErrUndecidedBR.Error()) - - //12 add one vote for br1, then we have 1/3W+1 votes - fmt.Println("adding 4th block vote to make up to match 1/3W+1") - e = fakeEvent(1, 0, true, 2, 8, br1Hash) - bv = inter.AsSignedBlockVotes(e) - require.NoError(t, env.ProcessBlockVotes(bv)) - - // 13. create one more record of the same block, but different. - br2 := ibr.LlrIdxFullBlockRecord{LlrFullBlockRecord: ibr.LlrFullBlockRecord{GasUsed: 100505}, Idx: idx.Block(2)} - - // 14. process br2. It should output an error, that block record hash is mismatched. - require.EqualError(t, env.ProcessFullBlockRecord(br2), errors.New("block record hash mismatch").Error()) - - // 15 process br1 - require.NoError(t, env.ProcessFullBlockRecord(br1)) - - //16 process br1 and br2, they should yield an error that they have been already processed - require.EqualError(t, env.ProcessFullBlockRecord(br1), eventcheck.ErrAlreadyProcessedBR.Error()) - require.EqualError(t, env.ProcessFullBlockRecord(br2), eventcheck.ErrAlreadyProcessedBR.Error()) -} - -// can not import it from inter package ((( - -func fakeEvent(bvsNum int, bvEpoch idx.Epoch, ersNum bool, evEpoch idx.Epoch, valID int, recordHash hash.Hash) *inter.EventPayload { - random := &inter.MutableEventPayload{} - r := rand.New(rand.NewSource(int64(0))) - random.SetVersion(1) - random.SetEpoch(2) - random.SetNetForkID(0) - random.SetLamport(idx.Lamport(rand.Intn(100) + 900)) - random.SetExtra([]byte{byte(r.Uint32())}) - random.SetSeq(idx.Event(r.Uint32() >> 8)) - random.SetCreator(idx.ValidatorID(valID)) - random.SetFrame(idx.Frame(r.Uint32() >> 16)) - random.SetCreationTime(inter.Timestamp(r.Uint64())) - random.SetMedianTime(inter.Timestamp(r.Uint64())) - random.SetGasPowerUsed(r.Uint64()) - random.SetGasPowerLeft(inter.GasPowerLeft{[2]uint64{r.Uint64(), r.Uint64()}}) - - bvs := inter.LlrBlockVotes{} - if bvsNum > 0 { - bvs.Start = 2 - switch { - case bvEpoch > 0: - bvs.Epoch = bvEpoch - random.SetEpoch(bvEpoch) - default: - bvs.Epoch = 1 - random.SetEpoch(1) - } - } - - for i := 0; i < bvsNum; i++ { - bvs.Votes = append(bvs.Votes, recordHash) - } - - ev := inter.LlrEpochVote{} - if ersNum { - ev.Epoch = evEpoch - ev.Vote = recordHash - } - - random.SetEpochVote(ev) - random.SetBlockVotes(bvs) - random.SetPayloadHash(inter.CalcPayloadHash(random)) - - parent := inter.MutableEventPayload{} - parent.SetVersion(1) - parent.SetLamport(random.Lamport() - 500) - parent.SetEpoch(random.Epoch()) - random.SetParents(hash.Events{parent.Build().ID()}) - - return random.Build() -} - -func randBig(r *rand.Rand) *big.Int { - b := make([]byte, r.Intn(8)) - _, _ = r.Read(b) - if len(b) == 0 { - b = []byte{0} - } - return new(big.Int).SetBytes(b) -} - -func randBytes(r *rand.Rand, size int) []byte { - b := make([]byte, size) - r.Read(b) - return b -} - -func randAddrPtr(r *rand.Rand) *common.Address { - addr := randAddr(r) - return &addr -} - -func randAddr(r *rand.Rand) common.Address { - addr := common.Address{} - r.Read(addr[:]) - return addr -} - -func randAccessList(r *rand.Rand, maxAddrs, maxKeys int) types.AccessList { - accessList := make(types.AccessList, r.Intn(maxAddrs)) - for i := range accessList { - accessList[i].Address = randAddr(r) - accessList[i].StorageKeys = make([]common.Hash, r.Intn(maxKeys)) - for j := range accessList[i].StorageKeys { - r.Read(accessList[i].StorageKeys[j][:]) - } - } - return accessList -} - -func TestEpochRecordWithDiffValidators(t *testing.T) { - const ( - validatorsNum = 10 - startEpoch = 2 - ) - require := require.New(t) - // setup testEnv - env := newTestEnv(startEpoch, validatorsNum) - - // Стартвые валидаторы имеют равномерные веса, стартовая эпоха - 2 - bs, es := env.store.GetHistoryBlockEpochState(startEpoch) - - // get new validators with different votes - newVals := func() *pos.Validators { - builder := pos.NewBuilder() - defaultWeight := pos.Weight(111022302) - for i := idx.ValidatorID(1); i <= 10; i++ { - w := defaultWeight - if i%2 == 0 { - w -= 10021567 - } else { - w += 10021567 - } - builder.Set(i, w) - } - return builder.Build() - }() - - // save new validators to state of epoch 2 - esCopy := es.Copy() - esCopy.Validators = newVals - - // process ER of 3rd epoch - er := ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, esCopy}, - Idx: idx.Epoch(startEpoch + 1), - } - erHash := er.Hash() - - for i := 1; i <= 4; i++ { - e := fakeEvent(0, 0, true, startEpoch+1, i, erHash) - ev := inter.AsSignedEpochVote(e) - // process validators with equal weights - require.NoError(env.ProcessEpochVote(ev)) - } - - require.NoError(env.ProcessFullEpochRecord(er)) - - // process ER of 4th epoch with validators with different weights - - // get bs and es of 3rd apoch - bs, es = env.store.GetHistoryBlockEpochState(startEpoch + 1) - - // put es and bs of 3rd apoch at LlrIdxFullEpochRecord of epoch 4 - er = ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, *es}, - Idx: idx.Epoch(startEpoch + 2)} - erHash = er.Hash() - - // confirm with votes of different weights - for i := 1; i <= 5; i++ { - e := fakeEvent(0, 0, true, startEpoch+2, i, erHash) - ev := inter.AsSignedEpochVote(e) - require.NoError(env.ProcessEpochVote(ev)) - } - - // process ER of epoch 4 - require.NoError(env.ProcessFullEpochRecord(er)) - - // process ER for epoch 5 and yield an error cause the total weight of validators is less than threshold 1/3W+1 - bs, es = env.store.GetHistoryBlockEpochState(startEpoch + 2) - - // yield validators with unequal weights to process in epoch 6 - newVals, partialWeight := func() (*pos.Validators, pos.Weight) { - builder := pos.NewBuilder() - w := pos.Weight(1000) - - // set 7 validators with weight 1000 - var partialWeight pos.Weight - for i := idx.ValidatorID(1); i <= 7; i++ { - partialWeight += w - builder.Set(i, w) - } - - w = pos.Weight(1000000) - //set 8th, 9th and 10th validatora with weight 1000000 - for i := idx.ValidatorID(8); i <= 10; i++ { - builder.Set(i, w) - } - - return builder.Build(), partialWeight - }() - - // save new validators to state - esCopy = es.Copy() - esCopy.Validators = newVals - - er = ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, esCopy}, - Idx: idx.Epoch(startEpoch + 3), - } - erHash = er.Hash() - - for i := 1; i <= 10; i++ { - e := fakeEvent(0, 0, true, startEpoch+3, i, erHash) - ev := inter.AsSignedEpochVote(e) - require.NoError(env.ProcessEpochVote(ev)) - } - - require.NoError(env.ProcessFullEpochRecord(er)) - - // process ER with epoch 6 - bs, es = env.store.GetHistoryBlockEpochState(startEpoch + 3) - - er = ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, *es}, - Idx: idx.Epoch(startEpoch + 4), - } - erHash = er.Hash() - - for i := 1; i <= 7; i++ { - e := fakeEvent(0, 0, true, startEpoch+4, i, erHash) - ev := inter.AsSignedEpochVote(e) - require.NoError(env.ProcessEpochVote(ev)) - } - - // process ER for epoch 6 - // threshold weight is 1002334 = 1/3W+1 - // 7 validators with total weight 7000 is less than threshold weight - // so 7 votes are not enough - totalWeight := newVals.TotalWeight() - thresholdWeight := pos.Weight(totalWeight/3 + 1) - require.Less(partialWeight, thresholdWeight) - require.EqualError(env.ProcessFullEpochRecord(er), eventcheck.ErrUndecidedER.Error()) -} - -func TestProcessEpochVotesWonErNil(t *testing.T) { - - const ( - validatorsNum = 10 - startEpoch = 2 - ) - - require := require.New(t) - - // setup testEnv - env := newTestEnv(startEpoch, validatorsNum) - - newVals, partialWeight := func() (*pos.Validators, pos.Weight) { - builder := pos.NewBuilder() - w := pos.Weight(1000) - - // set 5 validators with weight 1000 - var partialWeight pos.Weight - for i := idx.ValidatorID(1); i < 5; i++ { - partialWeight += w - builder.Set(i, w) - } - - w = pos.Weight(10000) - //set 8th, 9th and 10th validatora with weight 10000 - for i := idx.ValidatorID(5); i <= 10; i++ { - builder.Set(i, w) - if i == idx.ValidatorID(9) || i == idx.ValidatorID(10) { - continue - } - partialWeight += w - } - - return builder.Build(), partialWeight - }() - - bs, es := env.store.GetHistoryBlockEpochState(startEpoch) - - esCopy := es.Copy() - esCopy.Validators = newVals - - er := ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, esCopy}, - Idx: idx.Epoch(startEpoch + 1), - } - erHash := er.Hash() - - // process validators with equal weights - for i := 1; i <= 4; i++ { - e := fakeEvent(0, 0, true, startEpoch+1, i, erHash) - ev := inter.AsSignedEpochVote(e) - require.NoError(env.ProcessEpochVote(ev)) - } - - require.NoError(env.ProcessFullEpochRecord(er)) - - bs, es = env.store.GetHistoryBlockEpochState(startEpoch + 1) - - er = ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, *es}, - Idx: idx.Epoch(startEpoch + 2), - } - erHash = er.Hash() - - // process validators with inequal weighs - // total weights of all validators - for i := 1; i <= 8; i++ { - e := fakeEvent(0, 0, true, startEpoch+2, i, erHash) - ev := inter.AsSignedEpochVote(e) - require.NoError(env.ProcessEpochVote(ev)) - } - - res := env.store.GetLlrEpochResult(startEpoch + 2) - require.NotNil(res) - require.NotNil(erHash.Hex(), res.Hex()) - - llrs := env.store.GetLlrState() - actualLowestEpochToDecide := llrs.LowestEpochToDecide - expectedLowestEpochToDecide := idx.Epoch(actualizeLowestIndex(uint64(llrs.LowestEpochToDecide), uint64(startEpoch+2), - func(u uint64) bool { - return env.store.GetLlrEpochResult(idx.Epoch(u)) != nil - })) - require.Equal(actualLowestEpochToDecide, expectedLowestEpochToDecide) - - totalWeight := newVals.TotalWeight() - thresholdWeight := pos.Weight(totalWeight/3 + 1) - require.GreaterOrEqual(partialWeight, thresholdWeight) - - require.NoError(env.ProcessFullEpochRecord(er)) -} - -func TestProcessEpochVotesWonErNotNilDoubleSign(t *testing.T) { - - const ( - validatorsNum = 10 - startEpoch = 2 - ) - - require := require.New(t) - - // setup testEnv - env := newTestEnv(startEpoch, validatorsNum) - - newVals := func() *pos.Validators { - builder := pos.NewBuilder() - w := pos.Weight(1000) - - //thresholdweight totalWeight(8200)/3 +1 = 2734 - // set 8 validators with weight 1000 - - for i := idx.ValidatorID(1); i <= 8; i++ { - //partialWeight += w - builder.Set(i, w) - } - - w = pos.Weight(100) - //set 9th and 10th validatora with weight 100 - for i := idx.ValidatorID(9); i <= 10; i++ { - builder.Set(i, w) - } - - return builder.Build() - }() - - bs, es := env.store.GetHistoryBlockEpochState(startEpoch) - - esCopy := es.Copy() - esCopy.Validators = newVals - - er := ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, esCopy}, - Idx: idx.Epoch(startEpoch + 1), - } - erHash := er.Hash() - - // process validators with equal weights - for i := 1; i <= 4; i++ { - e := fakeEvent(0, 0, true, startEpoch+1, i, erHash) - ev := inter.AsSignedEpochVote(e) - require.NoError(env.ProcessEpochVote(ev)) - } - - require.NoError(env.ProcessFullEpochRecord(er)) - - bs, es = env.store.GetHistoryBlockEpochState(startEpoch + 1) - - er = ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, *es}, - Idx: idx.Epoch(startEpoch + 2), - } - - require.Equal(er.Hash().Hex(), erHash.Hex()) - - // process validators with inequal weighs - for i := 1; i <= 3; i++ { - e := fakeEvent(0, 0, true, startEpoch+2, i, erHash) - ev := inter.AsSignedEpochVote(e) - require.NoError(env.ProcessEpochVote(ev)) - - // output error if an event has been previously processed - require.EqualError(env.ProcessEpochVote(ev), eventcheck.ErrAlreadyProcessedEV.Error()) - } - - res1 := env.store.GetLlrEpochResult(startEpoch + 2) - require.Equal(res1.Hex(), erHash.Hex()) - - // Unvoted validators submit their votes for invalid hash record to cause doublesign - // the weight of these validators is 3000 that is >= w/3+1 - invalidHash := hash.HexToHash("0x12") - for i := 5; i <= 7; i++ { - e := fakeEvent(0, 0, true, startEpoch+2, i, invalidHash) - ev := inter.AsSignedEpochVote(e) - require.NoError(env.ProcessEpochVote(ev)) - } - - // checking double sign - wonEr := env.store.GetLlrEpochResult(startEpoch + 2) // erHash - require.NotNil(wonEr) // wonEr != nil - require.Equal(wonEr.Hex(), erHash.Hex()) - require.NotEqual(wonEr.Hex(), invalidHash.Hex()) // *wonEr != ev - - // processing an event with incorrect epoch will result in eventcheck.ErrUnknownEpochEV error - i := 9 - invalidEpoch := idx.Epoch(1) - e := fakeEvent(0, 0, true, invalidEpoch, i, erHash) - require.EqualError(env.ProcessEpochVote(inter.AsSignedEpochVote(e)), eventcheck.ErrUnknownEpochEV.Error()) - - // processing an event with incorrect epoch will result in eventcheck.ErrUnknownEpochEV error - i = 10 - invalidEpoch = idx.Epoch(20) - e = fakeEvent(0, 0, true, invalidEpoch, i, erHash) - require.EqualError(env.ProcessEpochVote(inter.AsSignedEpochVote(e)), eventcheck.ErrUnknownEpochEV.Error()) - - require.NoError(env.ProcessFullEpochRecord(er)) - - // check that unvoted validators with less weight than 1/3w+1 can not damage LLR - - bs, es = env.store.GetHistoryBlockEpochState(startEpoch + 2) - - er = ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, *es}, - Idx: idx.Epoch(startEpoch + 3), - } - - // total weight = 2000, threshold 1/3w+1 is 2733 - for i := 1; i < 3; i++ { - e := fakeEvent(0, 0, true, startEpoch+3, i, invalidHash) - ev := inter.AsSignedEpochVote(e) - require.NoError(env.ProcessEpochVote(ev)) - } - - wonEr = env.store.GetLlrEpochResult(startEpoch + 3) - require.Nil(wonEr) - - require.EqualError(env.ProcessFullEpochRecord(er), eventcheck.ErrUndecidedER.Error()) -} - -func TestProcessBlockVotesDoubleSign(t *testing.T) { - const ( - validatorsNum = 10 - startEpoch = 1 - ) - - require := require.New(t) - - // setup testEnv - env := newTestEnv(startEpoch, validatorsNum) - - br1 := ibr.LlrIdxFullBlockRecord{Idx: idx.Block(2)} - br1Hash := br1.Hash() - - // adding 4 votes for br1 it excceeds 1/3W+1 since all weights are equal - for i := 1; i <= 4; i++ { - e := fakeEvent(1, 0, false, 0, i, br1Hash) - bv := inter.AsSignedBlockVotes(e) - require.NoError(env.ProcessBlockVotes(bv)) - require.EqualError(env.ProcessBlockVotes(bv), eventcheck.ErrAlreadyProcessedBVs.Error()) - } - - wonBr := env.store.GetLlrBlockResult(idx.Block(2)) - require.NotNil(wonBr) - require.Equal(wonBr.Hex(), br1Hash.Hex()) - - // compare llrs.LowestBlockToDecide - llrs := env.store.GetLlrState() - actualLowestBlockToDecide := llrs.LowestBlockToDecide - expectedLowestBlockToDecide := idx.Block(actualizeLowestIndex(uint64(llrs.LowestBlockToDecide), uint64(2), func(u uint64) bool { - return env.store.GetLlrBlockResult(idx.Block(u)) != nil - })) - require.Equal(actualLowestBlockToDecide, expectedLowestBlockToDecide) - - // doublesign scenario - invalidHash := hash.HexToHash("0x12") - for i := 1; i <= 4; i++ { - e := fakeEvent(1, 0, false, 0, i, invalidHash) - bv := inter.AsSignedBlockVotes(e) - require.NoError(env.ProcessBlockVotes(bv)) - } - - wonBr = env.store.GetLlrBlockResult(idx.Block(2)) //br1Hash - require.NotNil(wonBr) - require.NotEqual(wonBr.Hex(), invalidHash.Hex()) // *wonBr != bv -} - -/* - -Blockvotes test cases -1) hash of block record incorrect, block N does not belong epoch E, -block vote for correct/incorrect hash -validators from enother epoch -2) hash of block record correct, block N does not belong epoch E, block vote for correct/incorrect hash validators >= 1/3W ,validators <=1/3W -> error anticipated -3) hash of block record correct, block N belongs epoch E, block vote for correct/incorrect hash validators >= 1/3W ,validators <=1/3W - - -Переменные Значения -hash of block record correct | incorrect -block N belongs to epoch E | does not belong to epoch E -validators have total weight <= 1/3W | have total weights >= 1/3W | vote for correct/incorrect hash record | vote for correct/ incorrect epoch | have equal weights or not | vote for block N or for incorrect block - -vote for a block - - -type BlockCtx struct { - Idx idx.Block - Time inter.Timestamp - Atropos hash.Event -} - - highestBlock.Idx = blockIdx - highestBlock.Atropos = block.Atropos - highestBlock.Time = block.Time - blockproc.BlockState{ - LastBlock: highestBlock, - - } - -TODO test with not random validators - -*/ - -func TestBlockVotesTests(t *testing.T) { - const ( - validatorsNum = 10 - startEpoch = 1 - ) - - require := require.New(t) - - // setup testEnv - env := newTestEnv(startEpoch, validatorsNum) - - bs, es := env.store.GetHistoryBlockEpochState(startEpoch) - - newVals := func() *pos.Validators { - builder := pos.NewBuilder() - w := pos.Weight(1000) - - //thresholdweight totalWeight(8200)/3 +1 = 2734 - // set 8 validators with weight 1000 - - for i := idx.ValidatorID(1); i <= 8; i++ { - //partialWeight += w - builder.Set(i, w) - } - - w = pos.Weight(100) - //set 9th and 10th validatora with weight 100 - for i := idx.ValidatorID(9); i <= 10; i++ { - builder.Set(i, w) - } - - return builder.Build() - }() - - // save new validators to state of epoch 2 - esCopy := es.Copy() - esCopy.Validators = newVals - - // process ER of 3rd epoch - er := ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, esCopy}, - Idx: idx.Epoch(startEpoch + 1), - } - erHash := er.Hash() - - incorrectValEvent := fakeEvent(0, 0, true, startEpoch+1, validatorsNum+1, erHash) - ev := inter.AsSignedEpochVote(incorrectValEvent) - require.NoError(env.checkers.Basiccheck.ValidateEV(ev)) - require.EqualError(env.checkers.Heavycheck.ValidateEV(ev), epochcheck.ErrAuth.Error()) - require.EqualError(env.ProcessEpochVote(ev), errValidatorNotExist.Error()) - - for i := 1; i <= 4; i++ { - e := fakeEvent(0, 0, true, startEpoch+1, i, erHash) - ev := inter.AsSignedEpochVote(e) - // process validators with equal weights - require.NoError(env.checkers.Basiccheck.ValidateEV(ev)) - // TODO debug it require.NoError(env.checkers.Heavycheck.ValidateEV(ev)) - require.NoError(env.ProcessEpochVote(ev)) - } - - require.NoError(env.ProcessFullEpochRecord(er)) - - bs, es = env.store.GetHistoryBlockEpochState(startEpoch + 1) - - er = ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{*bs, *es}, - Idx: idx.Epoch(startEpoch + 2)} - erHash = er.Hash() - - br := ibr.LlrIdxFullBlockRecord{Idx: idx.Block(2)} - brHash := br.Hash() - - //we can votr for validators with the different weights - incorrectBVEpoch := idx.Epoch(3) - e := fakeEvent(1, incorrectBVEpoch, false, 0, 1, brHash) - bvs := inter.AsSignedBlockVotes(e) - require.NoError(env.checkers.Basiccheck.ValidateBVs(bvs)) - // require.NoError(env.checkers.Heavycheck.ValidateBVs(bvs)) debug it event has whone signature - require.EqualError(env.ProcessBlockVotes(bvs), eventcheck.ErrUnknownEpochBVs.Error()) - - // ьфлу туц е - - //require.EqualError(env.ProcessBlockVotes(bvs), eventcheck.ErrAlreadyProcessedBVs.Error()) - - /* - for i := 5; i < 8; i++ { - e := fakeEvent(20, 0, false, 0, i, brHash) - bvs := inter.AsSignedBlockVotes(e) - require.NoError(env.checkers.Basiccheck.ValidateBVs(bvs)) - require.NoError(env.checkers.Heavycheck.ValidateBVs(bvs)) - require.NoError(env.ProcessBlockVotes(bvs)) - } - */ -} - -func fakeEventWithLamport(bv inter.LlrBlockVotes, ev inter.LlrEpochVote, lamport idx.Lamport) *inter.EventPayload { - me := &inter.MutableEventPayload{} - me.SetVersion(1) - me.SetEpoch(2) - me.SetNetForkID(0) - me.SetLamport(lamport) - me.SetCreator(idx.ValidatorID(1)) - me.SetBlockVotes(bv) - me.SetEpochVote(ev) - me.SetPayloadHash(inter.CalcPayloadHash(me)) - return me.Build() -} - -func TestProcessBlockVotesOneValidatorMultipleBvs(t *testing.T) { - t.Skip() // skip until fixed - const ( - validatorsNum = 10 - startEpoch = 2 - ) - - br := ibr.LlrIdxFullBlockRecord{Idx: idx.Block(2)} - brHash := br.Hash() - - require := require.New(t) - - getBv := func(start idx.Block, epoch idx.Epoch, vote hash.Hash, bvNum int) inter.LlrBlockVotes { - bv := inter.LlrBlockVotes{ - Start: start, - Epoch: epoch, - } - - for i := 0; i < bvNum; i++ { - bv.Votes = append(bv.Votes, vote) - } - - return bv - } - - testCases := []struct { - name string - pretest func(*testEnv) - }{ - { - "bv with different Start", - func(env *testEnv) { - EventWithBvCorrectStart := fakeEventWithLamport(getBv(2, 2, brHash, 1), inter.LlrEpochVote{}, idx.Lamport(rand.Intn(100))) - require.NoError(env.ProcessBlockVotes(inter.AsSignedBlockVotes(EventWithBvCorrectStart))) - - randLamport := idx.Lamport(rand.Intn(100)) - for i := 0; i < 9; i++ { - bv := getBv(idx.Block(i+1), 2, brHash, 1) - e := fakeEventWithLamport(bv, inter.LlrEpochVote{}, randLamport) - require.NoError(env.ProcessBlockVotes(inter.AsSignedBlockVotes(e))) - } - }, - }, - { - "bv with different votes", - func(env *testEnv) { - randLamport := idx.Lamport(rand.Intn(100)) - for i := 0; i < 10; i++ { - bv := getBv(2, 2, brHash, i) - e := fakeEventWithLamport(bv, inter.LlrEpochVote{}, randLamport) - require.NoError(env.ProcessBlockVotes(inter.AsSignedBlockVotes(e))) - } - }, - }, - { - "bv with different Lamport", - func(env *testEnv) { - bv := getBv(2, 2, brHash, 1) - for i := 0; i < 9; i++ { - randLamport := idx.Lamport(rand.Intn(1000)) - e := fakeEventWithLamport(bv, inter.LlrEpochVote{}, randLamport) - require.NoError(env.ProcessBlockVotes(inter.AsSignedBlockVotes(e))) - } - }, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - env := newTestEnv(startEpoch, validatorsNum) - tc.pretest(env) - require.EqualError(env.ProcessFullBlockRecord(br), eventcheck.ErrUndecidedBR.Error()) - }) - } -} - -func TestProcessEpochVotesOneValidatorMultipleEvsDiffLamport(t *testing.T) { - const ( - validatorsNum = 10 - startEpoch = 2 - ) - - require := require.New(t) - - getEv := func(epoch idx.Epoch, vote hash.Hash) inter.LlrEpochVote { - return inter.LlrEpochVote{ - Epoch: epoch, - Vote: vote, - } - } - - env := newTestEnv(startEpoch, validatorsNum) - - er := ier.LlrIdxFullEpochRecord{Idx: idx.Epoch(startEpoch) + 1} - erHash := er.Hash() - - for i := 0; i < 10; i++ { - randLamport := idx.Lamport(rand.Intn(1000)) - e := fakeEventWithLamport(inter.LlrBlockVotes{}, getEv(startEpoch+1, erHash), randLamport) - require.NoError(env.ProcessEpochVote(inter.AsSignedEpochVote(e))) - } - - require.EqualError(env.ProcessFullEpochRecord(er), eventcheck.ErrUndecidedER.Error()) -} diff --git a/evm/go-x1/gossip/checker_helpers.go b/evm/go-x1/gossip/checker_helpers.go deleted file mode 100644 index 73ebf24..0000000 --- a/evm/go-x1/gossip/checker_helpers.go +++ /dev/null @@ -1,119 +0,0 @@ -package gossip - -import ( - "sync/atomic" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - - "github.com/Fantom-foundation/go-opera/eventcheck/gaspowercheck" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/opera" -) - -// GasPowerCheckReader is a helper to run gas power check -type GasPowerCheckReader struct { - Ctx atomic.Value -} - -// GetValidationContext returns current validation context for gaspowercheck -func (r *GasPowerCheckReader) GetValidationContext() *gaspowercheck.ValidationContext { - return r.Ctx.Load().(*gaspowercheck.ValidationContext) -} - -// NewGasPowerContext reads current validation context for gaspowercheck -func NewGasPowerContext(s *Store, validators *pos.Validators, epoch idx.Epoch, cfg opera.EconomyRules) *gaspowercheck.ValidationContext { - // engineMu is locked here - - short := cfg.ShortGasPower - shortTermConfig := gaspowercheck.Config{ - Idx: inter.ShortTermGas, - AllocPerSec: short.AllocPerSec, - MaxAllocPeriod: short.MaxAllocPeriod, - MinEnsuredAlloc: cfg.Gas.MaxEventGas, - StartupAllocPeriod: short.StartupAllocPeriod, - MinStartupGas: short.MinStartupGas, - } - - long := cfg.LongGasPower - longTermConfig := gaspowercheck.Config{ - Idx: inter.LongTermGas, - AllocPerSec: long.AllocPerSec, - MaxAllocPeriod: long.MaxAllocPeriod, - MinEnsuredAlloc: cfg.Gas.MaxEventGas, - StartupAllocPeriod: long.StartupAllocPeriod, - MinStartupGas: long.MinStartupGas, - } - - validatorStates := make([]gaspowercheck.ValidatorState, validators.Len()) - es := s.GetEpochState() - for i, val := range es.ValidatorStates { - validatorStates[i].GasRefund = val.GasRefund - validatorStates[i].PrevEpochEvent = val.PrevEpochEvent - } - - return &gaspowercheck.ValidationContext{ - Epoch: epoch, - Validators: validators, - EpochStart: es.EpochStart, - ValidatorStates: validatorStates, - Configs: [inter.GasPowerConfigs]gaspowercheck.Config{ - inter.ShortTermGas: shortTermConfig, - inter.LongTermGas: longTermConfig, - }, - } -} - -// ValidatorsPubKeys stores info to authenticate validators -type ValidatorsPubKeys struct { - Epoch idx.Epoch - PubKeys map[idx.ValidatorID]validatorpk.PubKey -} - -// HeavyCheckReader is a helper to run heavy power checks -type HeavyCheckReader struct { - Pubkeys atomic.Value - Store *Store -} - -// GetEpochPubKeys is safe for concurrent use -func (r *HeavyCheckReader) GetEpochPubKeys() (map[idx.ValidatorID]validatorpk.PubKey, idx.Epoch) { - auth := r.Pubkeys.Load().(*ValidatorsPubKeys) - - return auth.PubKeys, auth.Epoch -} - -// GetEpochPubKeysOf is safe for concurrent use -func (r *HeavyCheckReader) GetEpochPubKeysOf(epoch idx.Epoch) map[idx.ValidatorID]validatorpk.PubKey { - auth := readEpochPubKeys(r.Store, epoch) - if auth == nil { - return nil - } - return auth.PubKeys -} - -// GetEpochBlockStart is safe for concurrent use -func (r *HeavyCheckReader) GetEpochBlockStart(epoch idx.Epoch) idx.Block { - bs, _ := r.Store.GetHistoryBlockEpochState(epoch) - if bs == nil { - return 0 - } - return bs.LastBlock.Idx -} - -// readEpochPubKeys reads epoch pubkeys -func readEpochPubKeys(s *Store, epoch idx.Epoch) *ValidatorsPubKeys { - es := s.GetHistoryEpochState(epoch) - if es == nil { - return nil - } - var pubkeys = make(map[idx.ValidatorID]validatorpk.PubKey, len(es.ValidatorProfiles)) - for id, profile := range es.ValidatorProfiles { - pubkeys[id] = profile.PubKey - } - return &ValidatorsPubKeys{ - Epoch: epoch, - PubKeys: pubkeys, - } -} diff --git a/evm/go-x1/gossip/common_test.go b/evm/go-x1/gossip/common_test.go deleted file mode 100644 index 5d2c4b8..0000000 --- a/evm/go-x1/gossip/common_test.go +++ /dev/null @@ -1,546 +0,0 @@ -package gossip - -import ( - "context" - "crypto/ecdsa" - "errors" - "fmt" - "math" - "math/big" - "sync" - "time" - - "github.com/Fantom-foundation/lachesis-base/abft" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/blockproc" - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/utils" - "github.com/Fantom-foundation/go-opera/utils/adapters/vecmt2dagidx" - "github.com/Fantom-foundation/go-opera/valkeystore" - "github.com/Fantom-foundation/go-opera/vecmt" -) - -const ( - gasLimit = uint64(21000) - maxGasLimit = uint64(6000000) - genesisBalance = 1e18 - genesisStake = 2 * 4e6 - - maxEpochDuration = time.Hour - sameEpoch = maxEpochDuration / 1000 - nextEpoch = maxEpochDuration -) - -type callbacks struct { - buildEvent func(e *inter.MutableEventPayload) - onEventConfirmed func(e inter.EventI) -} - -type testEnv struct { - t time.Time - nonces map[common.Address]uint64 - callback callbacks - *Service - signer valkeystore.SignerI - pubkeys []validatorpk.PubKey -} - -func panics(name string) func(error) { - return func(err error) { - log.Crit(fmt.Sprintf("%s error", name), "err", err) - } -} - -type testGossipStoreAdapter struct { - *Store -} - -func (g *testGossipStoreAdapter) GetEvent(id hash.Event) dag.Event { - e := g.Store.GetEvent(id) - if e == nil { - return nil - } - return e -} - -func makeTestEngine(gdb *Store) (*abft.Lachesis, *vecmt.Index) { - cdb := abft.NewMemStore() - _ = cdb.ApplyGenesis(&abft.Genesis{ - Epoch: gdb.GetEpoch(), - Validators: gdb.GetValidators(), - }) - vecClock := vecmt.NewIndex(panics("Vector clock"), vecmt.LiteConfig()) - engine := abft.NewLachesis(cdb, &testGossipStoreAdapter{gdb}, vecmt2dagidx.Wrap(vecClock), panics("Lachesis"), abft.LiteConfig()) - return engine, vecClock -} - -type testEmitterWorldExternal struct { - emitter.External - env *testEnv -} - -func (em testEmitterWorldExternal) Build(e *inter.MutableEventPayload, onIndexed func()) error { - e.SetCreationTime(inter.Timestamp(em.env.t.UnixNano())) - if em.env.callback.buildEvent != nil { - em.env.callback.buildEvent(e) - } - return em.External.Build(e, onIndexed) -} - -func (em testEmitterWorldExternal) Broadcast(*inter.EventPayload) {} - -type testConfirmedEventsProcessor struct { - blockproc.ConfirmedEventsProcessor - env *testEnv -} - -func (p testConfirmedEventsProcessor) ProcessConfirmedEvent(e inter.EventI) { - if p.env.callback.onEventConfirmed != nil { - p.env.callback.onEventConfirmed(e) - } - p.ConfirmedEventsProcessor.ProcessConfirmedEvent(e) -} - -type testConfirmedEventsModule struct { - blockproc.ConfirmedEventsModule - env *testEnv -} - -func (m testConfirmedEventsModule) Start(bs iblockproc.BlockState, es iblockproc.EpochState) blockproc.ConfirmedEventsProcessor { - p := m.ConfirmedEventsModule.Start(bs, es) - return testConfirmedEventsProcessor{p, m.env} -} - -func newTestEnv(firstEpoch idx.Epoch, validatorsNum idx.Validator) *testEnv { - rules := opera.FakeNetRules() - rules.Epochs.MaxEpochDuration = inter.Timestamp(maxEpochDuration) - rules.Blocks.MaxEmptyBlockSkipPeriod = 0 - - genStore := makefakegenesis.FakeGenesisStoreWithRulesAndStart(validatorsNum, utils.ToFtm(genesisBalance), utils.ToFtm(genesisStake), rules, firstEpoch, 2) - genesis := genStore.Genesis() - - store := NewMemStore() - _, err := store.ApplyGenesis(genesis) - if err != nil { - panic(err) - } - - // install blockProc callbacks - env := &testEnv{ - t: store.GetGenesisTime().Time(), - nonces: make(map[common.Address]uint64), - } - blockProc := DefaultBlockProc() - blockProc.EventsModule = testConfirmedEventsModule{blockProc.EventsModule, env} - - engine, vecClock := makeTestEngine(store) - - // create the service - txPool := &dummyTxPool{} - env.Service, err = newService(DefaultConfig(cachescale.Identity), store, blockProc, engine, vecClock, func(_ evmcore.StateReader) TxPool { - return txPool - }) - if err != nil { - panic(err) - } - txPool.signer = env.EthAPI.signer - err = engine.Bootstrap(env.GetConsensusCallbacks()) - if err != nil { - panic(err) - } - - valKeystore := valkeystore.NewDefaultMemKeystore() - env.signer = valkeystore.NewSigner(valKeystore) - - // register emitters - for i := idx.Validator(0); i < validatorsNum; i++ { - cfg := emitter.DefaultConfig() - vid := store.GetValidators().GetID(i) - pubkey := store.GetEpochState().ValidatorProfiles[vid].PubKey - cfg.Validator = emitter.ValidatorConfig{ - ID: vid, - PubKey: pubkey, - } - cfg.EmitIntervals = emitter.EmitIntervals{} - cfg.MaxParents = idx.Event(validatorsNum/2 + 1) - cfg.MaxTxsPerAddress = 10000000 - _ = valKeystore.Add(pubkey, crypto.FromECDSA(makefakegenesis.FakeKey(vid)), validatorpk.FakePassword) - _ = valKeystore.Unlock(pubkey, validatorpk.FakePassword) - world := env.EmitterWorld(env.signer) - world.External = testEmitterWorldExternal{world.External, env} - em := emitter.NewEmitter(cfg, world) - env.RegisterEmitter(em) - env.pubkeys = append(env.pubkeys, pubkey) - em.Start() - } - - _ = env.store.GenerateSnapshotAt(common.Hash(store.GetBlockState().FinalizedStateRoot), false) - env.blockProcTasks.Start(1) - env.verWatcher.Start() - - return env -} - -func (env *testEnv) Close() { - env.verWatcher.Stop() - env.store.Close() - env.tflusher.Stop() -} - -func (env *testEnv) GetEvmStateReader() *EvmStateReader { - return &EvmStateReader{ - store: env.store, - } -} - -func (env *testEnv) ApplyTxs(spent time.Duration, txs ...*types.Transaction) (types.Receipts, error) { - env.t = env.t.Add(spent) - - externalReceipts := make(types.Receipts, 0, len(txs)) - - env.txpool.AddRemotes(txs) - defer env.txpool.(*dummyTxPool).Clear() - newBlocks := make(chan evmcore.ChainHeadNotify) - chainHeadSub := env.feed.SubscribeNewBlock(newBlocks) - mu := &sync.Mutex{} - go func() { - for b := range newBlocks { - if len(b.Block.Transactions) == 0 { - continue - } - receipts := env.store.evm.GetReceipts(idx.Block(b.Block.Number.Uint64()), env.EthAPI.signer, b.Block.Hash, b.Block.Transactions) - for i, tx := range b.Block.Transactions { - if r, _, _ := tx.RawSignatureValues(); r.Sign() != 0 { - mu.Lock() - externalReceipts = append(externalReceipts, receipts[i]) - mu.Unlock() - env.txpool.(*dummyTxPool).Delete(tx.Hash()) - } - } - if externalReceipts.Len() == len(txs) { - chainHeadSub.Unsubscribe() - close(newBlocks) - break - } - } - }() - err := env.EmitUntil(func() bool { - mu.Lock() - defer mu.Unlock() - return externalReceipts.Len() == len(txs) - }) - - return externalReceipts, err -} - -func (env *testEnv) ApplyMPs(spent time.Duration, mps ...inter.MisbehaviourProof) error { - env.t = env.t.Add(spent) - - // all callbacks are non-async - lastEpoch := idx.Epoch(0) - env.callback.buildEvent = func(e *inter.MutableEventPayload) { - if e.Epoch() > lastEpoch { - e.SetMisbehaviourProofs(mps) - lastEpoch = e.Epoch() - } - } - confirmed := false - env.callback.onEventConfirmed = func(_e inter.EventI) { - // ensure that not only MPs were confirmed, but also no new MPs will be confirmed in future - if _e.AnyMisbehaviourProofs() && _e.Epoch() == lastEpoch { - confirmed = true - // sanity check for gas used - e := env.store.GetEventPayload(_e.ID()) - rule := env.store.GetRules().Economy.Gas - if e.GasPowerUsed() < rule.EventGas+uint64(len(e.MisbehaviourProofs()))*rule.MisbehaviourProofGas { - panic("GasPowerUsed calculation doesn't include MisbehaviourProofGas") - } - } - } - defer func() { - env.callback.buildEvent = nil - }() - - return env.EmitUntil(func() bool { - return confirmed - }) -} - -func (env *testEnv) EmitUntil(stop func() bool) error { - t := time.Now() - - for !stop() { - for _, em := range env.emitters { - _, err := em.EmitEvent() - if err != nil { - return err - } - } - env.WaitBlockEnd() - env.t = env.t.Add(time.Second) - if time.Since(t) > 30*time.Second { - panic("block doesn't get processed") - } - } - return nil -} - -func (env *testEnv) Transfer(from, to idx.ValidatorID, amount *big.Int) *types.Transaction { - sender := env.Address(from) - nonce, _ := env.PendingNonceAt(nil, sender) - env.incNonce(sender) - key := env.privateKey(from) - receiver := env.Address(to) - gp := new(big.Int).SetUint64(1e12) - tx := types.NewTransaction(nonce, receiver, amount, gasLimit, gp, nil) - tx, err := types.SignTx(tx, env.EthAPI.signer, key) - if err != nil { - panic(err) - } - - return tx -} - -func (env *testEnv) Contract(from idx.ValidatorID, amount *big.Int, hex string) *types.Transaction { - sender := env.Address(from) - nonce, _ := env.PendingNonceAt(nil, sender) - env.incNonce(sender) - key := env.privateKey(from) - gp := env.store.GetRules().Economy.MinGasPrice - data := hexutil.MustDecode(hex) - tx := types.NewContractCreation(nonce, amount, maxGasLimit, gp, data) - tx, err := types.SignTx(tx, env.EthAPI.signer, key) - if err != nil { - panic(err) - } - - return tx -} - -func (env *testEnv) privateKey(n idx.ValidatorID) *ecdsa.PrivateKey { - key := makefakegenesis.FakeKey(n) - return key -} - -func (env *testEnv) Address(n idx.ValidatorID) common.Address { - key := makefakegenesis.FakeKey(n) - addr := crypto.PubkeyToAddress(key.PublicKey) - return addr -} - -func (env *testEnv) Payer(n idx.ValidatorID, amounts ...*big.Int) *bind.TransactOpts { - key := env.privateKey(n) - t, _ := bind.NewKeyedTransactorWithChainID(key, new(big.Int).SetUint64(env.store.GetRules().NetworkID)) - nonce, _ := env.PendingNonceAt(nil, env.Address(n)) - t.Nonce = big.NewInt(int64(nonce)) - t.Value = big.NewInt(0) - for _, amount := range amounts { - t.Value.Add(t.Value, amount) - } - t.GasLimit = env.GetEvmStateReader().MaxGasLimit() - t.GasPrice = env.GetEvmStateReader().MinGasPrice() - - return t -} - -func (env *testEnv) Pay(n idx.ValidatorID, amounts ...*big.Int) *bind.TransactOpts { - t := env.Payer(n, amounts...) - env.incNonce(t.From) - - return t -} - -func (env *testEnv) ReadOnly() *bind.CallOpts { - return &bind.CallOpts{} -} - -func (env *testEnv) State() *state.StateDB { - statedb, _ := env.store.evm.StateDB(env.store.GetBlockState().FinalizedStateRoot) - return statedb -} - -func (env *testEnv) incNonce(account common.Address) { - env.nonces[account] += 1 -} - -/* - * bind.ContractCaller interface - */ - -var ( - errBlockNumberUnsupported = errors.New("simulatedBackend cannot access blocks other than the latest block") -) - -// CodeAt returns the code of the given account. This is needed to differentiate -// between contract internal errors and the local chain being out of sync. -func (env *testEnv) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) { - if blockNumber != nil && idx.Block(blockNumber.Uint64()) != env.store.GetLatestBlockIndex() { - return nil, errBlockNumberUnsupported - } - - code := env.State().GetCode(contract) - return code, nil -} - -// ContractCall executes an Ethereum contract call with the specified data as the -// input. -func (env *testEnv) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { - if blockNumber != nil && idx.Block(blockNumber.Uint64()) != env.store.GetLatestBlockIndex() { - return nil, errBlockNumberUnsupported - } - - h := env.GetEvmStateReader().GetHeader(common.Hash{}, uint64(env.store.GetLatestBlockIndex())) - block := &evmcore.EvmBlock{ - EvmHeader: *h, - } - - rval, _, _, err := env.callContract(ctx, call, block, env.State()) - return rval, err -} - -func (env *testEnv) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { - var num64 uint64 - if number == nil { - num64 = uint64(env.store.GetLatestBlockIndex()) - } else { - num64 = number.Uint64() - } - return env.GetEvmStateReader().GetHeader(common.Hash{}, num64).EthHeader(), nil -} - -// callContract implements common code between normal and pending contract calls. -// state is modified during execution, make sure to copy it if necessary. -func (env *testEnv) callContract( - ctx context.Context, call ethereum.CallMsg, block *evmcore.EvmBlock, state *state.StateDB, -) ( - ret []byte, usedGas uint64, failed bool, err error, -) { - // Ensure message is initialized properly. - if call.GasPrice == nil { - call.GasPrice = big.NewInt(1) - } - if call.Gas == 0 { - call.Gas = 50000000 - } - if call.Value == nil { - call.Value = new(big.Int) - } - // Set infinite balance to the fake caller account. - from := state.GetOrNewStateObject(call.From) - from.SetBalance(big.NewInt(math.MaxInt64)) - - msg := callmsg{call} - - // Create a new environment which holds all relevant information - // about the transaction and calling mechanisms. - txContext := evmcore.NewEVMTxContext(msg) - context := evmcore.NewEVMBlockContext(block.Header(), env.GetEvmStateReader(), nil) - vmenv := vm.NewEVM(context, txContext, state, env.store.GetEvmChainConfig(), opera.DefaultVMConfig) - gaspool := new(evmcore.GasPool).AddGas(math.MaxUint64) - res, err := evmcore.NewStateTransition(vmenv, msg, gaspool).TransitionDb() - - ret, usedGas, failed = res.Return(), res.UsedGas, res.Failed() - return -} - -/* - * bind.ContractTransactor interface - */ - -// PendingCodeAt returns the code of the given account in the pending state. -func (env *testEnv) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { - code := env.State().GetCode(account) - return code, nil -} - -// PendingNonceAt retrieves the current pending nonce associated with an account. -func (env *testEnv) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { - nonce := env.nonces[account] - return nonce, nil -} - -// SuggestGasTipCap retrieves the currently suggested gas price tip to allow a timely -// execution of a transaction. -func (env *testEnv) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { - return new(big.Int), nil -} - -// SuggestGasTipCap retrieves the currently suggested gas price to allow a timely -// execution of a transaction. -func (env *testEnv) SuggestGasPrice(ctx context.Context) (*big.Int, error) { - return env.store.GetRules().Economy.MinGasPrice, nil -} - -// EstimateGas tries to estimate the gas needed to execute a specific -// transaction based on the current pending state of the backend blockchain. -// There is no guarantee that this is the true gas limit requirement as other -// transactions may be added or removed by miners, but it should provide a basis -// for setting a reasonable default. -func (env *testEnv) EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) { - if call.To == nil { - gas = gasLimit * 10000 - } else { - gas = gasLimit * 10 - } - return -} - -// SendTransaction injects the transaction into the pending pool for execution. -func (env *testEnv) SendTransaction(ctx context.Context, tx *types.Transaction) error { - // do nothing to avoid executing by transactor, only generating needed - return nil -} - -/* - * bind.ContractFilterer interface - */ - -// FilterLogs executes a log filter operation, blocking during execution and -// returning all the results in one batch. -func (env *testEnv) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) { - panic("not implemented yet") - return nil, nil -} - -// SubscribeFilterLogs creates a background log filtering operation, returning -// a subscription immediately, which can be used to stream the found events. -func (env *testEnv) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { - panic("not implemented yet") - return nil, nil -} - -// callmsg implements evmcore.Message to allow passing it as a transaction simulator. -type callmsg struct { - ethereum.CallMsg -} - -func (m callmsg) From() common.Address { return m.CallMsg.From } -func (m callmsg) To() *common.Address { return m.CallMsg.To } -func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice } -func (m callmsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap } -func (m callmsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap } -func (m callmsg) Gas() uint64 { return m.CallMsg.Gas } -func (m callmsg) Value() *big.Int { return m.CallMsg.Value } -func (m callmsg) Nonce() uint64 { return 0 } -func (m callmsg) IsFake() bool { return true } -func (m callmsg) Data() []byte { return m.CallMsg.Data } -func (m callmsg) AccessList() types.AccessList { return nil } diff --git a/evm/go-x1/gossip/config.go b/evm/go-x1/gossip/config.go deleted file mode 100644 index 6f2c2e5..0000000 --- a/evm/go-x1/gossip/config.go +++ /dev/null @@ -1,299 +0,0 @@ -package gossip - -import ( - "fmt" - "math/big" - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/dagprocessor" - "github.com/Fantom-foundation/lachesis-base/gossip/itemsfetcher" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/go-opera/eventcheck/heavycheck" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/gossip/filters" - "github.com/Fantom-foundation/go-opera/gossip/gasprice" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brprocessor" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brstream/brstreamleecher" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brstream/brstreamseeder" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvprocessor" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvstream/bvstreamleecher" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvstream/bvstreamseeder" - "github.com/Fantom-foundation/go-opera/gossip/protocols/dag/dagstream/dagstreamleecher" - "github.com/Fantom-foundation/go-opera/gossip/protocols/dag/dagstream/dagstreamseeder" - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epprocessor" - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epstream/epstreamleecher" - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epstream/epstreamseeder" -) - -const nominalSize uint = 1 - -type ( - // ProtocolConfig is config for p2p protocol - ProtocolConfig struct { - // 0/M means "optimize only for throughput", N/0 means "optimize only for latency", N/M is a balanced mode - - LatencyImportance int - ThroughputImportance int - - EventsSemaphoreLimit dag.Metric - BVsSemaphoreLimit dag.Metric - MsgsSemaphoreLimit dag.Metric - MsgsSemaphoreTimeout time.Duration - - ProgressBroadcastPeriod time.Duration - - DagProcessor dagprocessor.Config - BvProcessor bvprocessor.Config - BrProcessor brprocessor.Config - EpProcessor epprocessor.Config - - DagFetcher itemsfetcher.Config - TxFetcher itemsfetcher.Config - DagStreamLeecher dagstreamleecher.Config - DagStreamSeeder dagstreamseeder.Config - BvStreamLeecher bvstreamleecher.Config - BvStreamSeeder bvstreamseeder.Config - BrStreamLeecher brstreamleecher.Config - BrStreamSeeder brstreamseeder.Config - EpStreamLeecher epstreamleecher.Config - EpStreamSeeder epstreamseeder.Config - - MaxInitialTxHashesSend int - MaxRandomTxHashesSend int - RandomTxHashesSendPeriod time.Duration - - PeerCache PeerCacheConfig - } - - // Config for the gossip service. - Config struct { - FilterAPI filters.Config - - // This can be set to list of enrtree:// URLs which will be queried for - // for nodes to connect to. - OperaDiscoveryURLs []string - SnapDiscoveryURLs []string - - AllowSnapsync bool - - TxIndex bool // Whether to enable indexing transactions and receipts or not - - // Protocol options - Protocol ProtocolConfig - - HeavyCheck heavycheck.Config - - // Gas Price Oracle options - GPO gasprice.Config - - // RPCGasCap is the global gas cap for eth-call variants. - RPCGasCap uint64 `toml:",omitempty"` - - // RPCEVMTimeout is the global timeout for eth-call. - RPCEVMTimeout time.Duration - - // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for - // send-transction variants. The unit is ether. - RPCTxFeeCap float64 `toml:",omitempty"` - - // RPCTimeout is a global time limit for RPC methods execution. - RPCTimeout time.Duration - - // allows only for EIP155 transactions. - AllowUnprotectedTxs bool - - RPCBlockExt bool - } - - StoreCacheConfig struct { - // Cache size for full events. - EventsNum int - EventsSize uint - // Cache size for event IDs - EventsIDsNum int - // Cache size for full blocks. - BlocksNum int - BlocksSize uint - // Cache size for history block/epoch states. - BlockEpochStateNum int - - LlrBlockVotesIndexes int - LlrEpochVotesIndexes int - } - - // StoreConfig is a config for store db. - StoreConfig struct { - Cache StoreCacheConfig - // EVM is EVM store config - EVM evmstore.StoreConfig - MaxNonFlushedSize int - MaxNonFlushedPeriod time.Duration - } -) - -type PeerCacheConfig struct { - MaxKnownTxs int // Maximum transactions hashes to keep in the known list (prevent DOS) - MaxKnownEvents int // Maximum event hashes to keep in the known list (prevent DOS) - // MaxQueuedItems is the maximum number of items to queue up before - // dropping broadcasts. This is a sensitive number as a transaction list might - // contain a single transaction, or thousands. - MaxQueuedItems idx.Event - MaxQueuedSize uint64 -} - -// DefaultConfig returns the default configurations for the gossip service. -func DefaultConfig(scale cachescale.Func) Config { - cfg := Config{ - FilterAPI: filters.DefaultConfig(), - - TxIndex: true, - - HeavyCheck: heavycheck.DefaultConfig(), - - Protocol: ProtocolConfig{ - LatencyImportance: 60, - ThroughputImportance: 40, - MsgsSemaphoreLimit: dag.Metric{ - Num: scale.Events(1000), - Size: scale.U64(30 * opt.MiB), - }, - EventsSemaphoreLimit: dag.Metric{ - Num: scale.Events(10000), - Size: scale.U64(30 * opt.MiB), - }, - BVsSemaphoreLimit: dag.Metric{ - Num: scale.Events(5000), - Size: scale.U64(15 * opt.MiB), - }, - MsgsSemaphoreTimeout: 10 * time.Second, - ProgressBroadcastPeriod: 10 * time.Second, - - DagProcessor: dagprocessor.DefaultConfig(scale), - BvProcessor: bvprocessor.DefaultConfig(scale), - BrProcessor: brprocessor.DefaultConfig(scale), - EpProcessor: epprocessor.DefaultConfig(scale), - DagFetcher: itemsfetcher.Config{ - ForgetTimeout: 1 * time.Minute, - ArriveTimeout: 1000 * time.Millisecond, - GatherSlack: 100 * time.Millisecond, - HashLimit: 20000, - MaxBatch: scale.I(512), - MaxQueuedBatches: scale.I(32), - MaxParallelRequests: 192, - }, - TxFetcher: itemsfetcher.Config{ - ForgetTimeout: 1 * time.Minute, - ArriveTimeout: 1000 * time.Millisecond, - GatherSlack: 100 * time.Millisecond, - HashLimit: 10000, - MaxBatch: scale.I(512), - MaxQueuedBatches: scale.I(32), - MaxParallelRequests: 64, - }, - DagStreamLeecher: dagstreamleecher.DefaultConfig(), - DagStreamSeeder: dagstreamseeder.DefaultConfig(scale), - BvStreamLeecher: bvstreamleecher.DefaultConfig(), - BvStreamSeeder: bvstreamseeder.DefaultConfig(scale), - BrStreamLeecher: brstreamleecher.DefaultConfig(), - BrStreamSeeder: brstreamseeder.DefaultConfig(scale), - EpStreamLeecher: epstreamleecher.DefaultConfig(), - EpStreamSeeder: epstreamseeder.DefaultConfig(scale), - MaxInitialTxHashesSend: 20000, - MaxRandomTxHashesSend: 128, - RandomTxHashesSendPeriod: 20 * time.Second, - PeerCache: DefaultPeerCacheConfig(scale), - }, - - RPCEVMTimeout: 5 * time.Second, - - GPO: gasprice.Config{ - MaxGasPrice: gasprice.DefaultMaxGasPrice, - MinGasPrice: new(big.Int), - MinGasTip: new(big.Int), - DefaultCertainty: 0.5 * gasprice.DecimalUnit, - }, - - RPCBlockExt: true, - - RPCGasCap: 50000000, - RPCTxFeeCap: 100, // 100 FTM - RPCTimeout: 5 * time.Second, - } - sessionCfg := cfg.Protocol.DagStreamLeecher.Session - cfg.Protocol.DagProcessor.EventsBufferLimit.Num = idx.Event(sessionCfg.ParallelChunksDownload)* - idx.Event(sessionCfg.DefaultChunkItemsNum) + softLimitItems - cfg.Protocol.DagProcessor.EventsBufferLimit.Size = uint64(sessionCfg.ParallelChunksDownload)*sessionCfg.DefaultChunkItemsSize + 8*opt.MiB - cfg.Protocol.DagStreamLeecher.MaxSessionRestart = 4 * time.Minute - cfg.Protocol.DagFetcher.ArriveTimeout = 4 * time.Second - cfg.Protocol.DagFetcher.HashLimit = 10000 - cfg.Protocol.TxFetcher.HashLimit = 10000 - - return cfg -} - -func (c *Config) Validate() error { - p := c.Protocol - defaultChunkSize := dag.Metric{idx.Event(p.DagStreamLeecher.Session.DefaultChunkItemsNum), p.DagStreamLeecher.Session.DefaultChunkItemsSize} - if defaultChunkSize.Num > hardLimitItems-1 { - return fmt.Errorf("DefaultChunkSize.Num has to be at not greater than %d", hardLimitItems-1) - } - if defaultChunkSize.Size > protocolMaxMsgSize/2 { - return fmt.Errorf("DefaultChunkSize.Num has to be at not greater than %d", protocolMaxMsgSize/2) - } - if p.EventsSemaphoreLimit.Num < 2*defaultChunkSize.Num || - p.EventsSemaphoreLimit.Size < 2*defaultChunkSize.Size { - return fmt.Errorf("EventsSemaphoreLimit has to be at least 2 times greater than %s (DefaultChunkSize)", defaultChunkSize.String()) - } - if p.EventsSemaphoreLimit.Num < 2*p.DagProcessor.EventsBufferLimit.Num || - p.EventsSemaphoreLimit.Size < 2*p.DagProcessor.EventsBufferLimit.Size { - return fmt.Errorf("EventsSemaphoreLimit has to be at least 2 times greater than %s (EventsBufferLimit)", p.DagProcessor.EventsBufferLimit.String()) - } - if p.EventsSemaphoreLimit.Size < 2*protocolMaxMsgSize { - return fmt.Errorf("EventsSemaphoreLimit.Size has to be at least %d", 2*protocolMaxMsgSize) - } - if p.MsgsSemaphoreLimit.Size < protocolMaxMsgSize { - return fmt.Errorf("MsgsSemaphoreLimit.Size has to be at least %d", protocolMaxMsgSize) - } - if p.DagProcessor.EventsBufferLimit.Size < protocolMaxMsgSize { - return fmt.Errorf("EventsBufferLimit.Size has to be at least %d", protocolMaxMsgSize) - } - - return nil -} - -// DefaultStoreConfig for product. -func DefaultStoreConfig(scale cachescale.Func) StoreConfig { - return StoreConfig{ - Cache: StoreCacheConfig{ - EventsNum: scale.I(5000), - EventsSize: scale.U(6 * opt.MiB), - EventsIDsNum: scale.I(100000), - BlocksNum: scale.I(5000), - BlocksSize: scale.U(512 * opt.KiB), - BlockEpochStateNum: scale.I(8), - LlrBlockVotesIndexes: scale.I(100), - LlrEpochVotesIndexes: scale.I(5), - }, - EVM: evmstore.DefaultStoreConfig(scale), - MaxNonFlushedSize: 21*opt.MiB + scale.I(2*opt.MiB), - MaxNonFlushedPeriod: 30 * time.Minute, - } -} - -// LiteStoreConfig is for tests or inmemory. -func LiteStoreConfig() StoreConfig { - return DefaultStoreConfig(cachescale.Ratio{Base: 10, Target: 1}) -} - -func DefaultPeerCacheConfig(scale cachescale.Func) PeerCacheConfig { - return PeerCacheConfig{ - MaxKnownTxs: 24576*3/4 + scale.I(24576/4), - MaxKnownEvents: 24576*3/4 + scale.I(24576/4), - MaxQueuedItems: 4096*3/4 + scale.Events(4096/4), - MaxQueuedSize: protocolMaxMsgSize*3/4 + 1024 + scale.U64(protocolMaxMsgSize/4), - } -} diff --git a/evm/go-x1/gossip/contract/ballot/Ballot.go b/evm/go-x1/gossip/contract/ballot/Ballot.go deleted file mode 100644 index c7aad02..0000000 --- a/evm/go-x1/gossip/contract/ballot/Ballot.go +++ /dev/null @@ -1,604 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package ballot - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// BallotMetaData contains all meta data concerning the Ballot contract. -var BallotMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposalNames\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"voteCount\",\"type\":\"uint256\"}],\"name\":\"NewProposal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"chairperson\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"}],\"name\":\"giveRightToVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"proposals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"voteCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposal\",\"type\":\"uint256\"}],\"name\":\"vote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"voters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"vote\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"winnerName\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"winnerName_\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"winningProposal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningProposal_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162001586380380620015868339818101604052810190620000379190620003b2565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555060005b8151811015620001e657600260405180604001604052808484815181106200010f576200010e62000403565b5b6020026020010151815260200160008152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550503373ffffffffffffffffffffffffffffffffffffffff167f4913a1b403184a1c69ab16947e9f4c7a1e48c069dccde91f2bf550ea77becc5b838381518110620001ae57620001ad62000403565b5b60200260200101516000604051620001c89291906200049a565b60405180910390a28080620001dd90620004f6565b915050620000e2565b505062000544565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620002528262000207565b810181811067ffffffffffffffff8211171562000274576200027362000218565b5b80604052505050565b600062000289620001ee565b905062000297828262000247565b919050565b600067ffffffffffffffff821115620002ba57620002b962000218565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b620002e581620002d0565b8114620002f157600080fd5b50565b6000815190506200030581620002da565b92915050565b6000620003226200031c846200029c565b6200027d565b90508083825260208201905060208402830185811115620003485762000347620002cb565b5b835b81811015620003755780620003608882620002f4565b8452602084019350506020810190506200034a565b5050509392505050565b600082601f83011262000397576200039662000202565b5b8151620003a98482602086016200030b565b91505092915050565b600060208284031215620003cb57620003ca620001f8565b5b600082015167ffffffffffffffff811115620003ec57620003eb620001fd565b5b620003fa848285016200037f565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6200043d81620002d0565b82525050565b6000819050919050565b6000819050919050565b6000819050919050565b6000620004826200047c620004768462000443565b62000457565b6200044d565b9050919050565b620004948162000461565b82525050565b6000604082019050620004b1600083018562000432565b620004c0602083018462000489565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000503826200044d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415620005395762000538620004c7565b5b600182019050919050565b61103280620005546000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063609ff1bd1161005b578063609ff1bd146101145780639e7b8d6114610132578063a3ec138d1461014e578063e2ba53f01461018157610088565b80630121b93f1461008d578063013cf08b146100a95780632e4176cf146100da5780635c19a95c146100f8575b600080fd5b6100a760048036038101906100a291906109e5565b61019f565b005b6100c360048036038101906100be91906109e5565b6102e6565b6040516100d1929190610a3a565b60405180910390f35b6100e261031a565b6040516100ef9190610aa4565b60405180910390f35b610112600480360381019061010d9190610aeb565b61033e565b005b61011c6106da565b6040516101299190610b18565b60405180910390f35b61014c60048036038101906101479190610aeb565b610762565b005b61016860048036038101906101639190610aeb565b610919565b6040516101789493929190610b4e565b60405180910390f35b610189610976565b6040516101969190610b93565b60405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561022a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022190610c0b565b60405180910390fd5b8060010160009054906101000a900460ff161561027c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027390610c77565b60405180910390fd5b60018160010160006101000a81548160ff0219169083151502179055508181600201819055508060000154600283815481106102bb576102ba610c97565b5b906000526020600020906002020160010160008282546102db9190610cf5565b925050819055505050565b600281815481106102f657600080fd5b90600052602060002090600202016000915090508060000154908060010154905082565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156103d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ca90610d97565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043990610e03565b60405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146105b257600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156105ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a490610e6f565b60405180910390fd5b610443565b60018160010160006101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156106b5578160000154600282600201548154811061068957610688610c97565b5b906000526020600020906002020160010160008282546106a99190610cf5565b925050819055506106d5565b81600001548160000160008282546106cd9190610cf5565b925050819055505b505050565b6000806000905060005b60028054905081101561075d57816002828154811061070657610705610c97565b5b906000526020600020906002020160010154111561074a576002818154811061073257610731610c97565b5b90600052602060002090600202016001015491508092505b808061075590610e8f565b9150506106e4565b505090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e790610f4a565b60405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1615610880576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087790610fb6565b60405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154146108cf57600080fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b600060026109826106da565b8154811061099357610992610c97565b5b906000526020600020906002020160000154905090565b600080fd5b6000819050919050565b6109c2816109af565b81146109cd57600080fd5b50565b6000813590506109df816109b9565b92915050565b6000602082840312156109fb576109fa6109aa565b5b6000610a09848285016109d0565b91505092915050565b6000819050919050565b610a2581610a12565b82525050565b610a34816109af565b82525050565b6000604082019050610a4f6000830185610a1c565b610a5c6020830184610a2b565b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b610ac881610a83565b8114610ad357600080fd5b50565b600081359050610ae581610abf565b92915050565b600060208284031215610b0157610b006109aa565b5b6000610b0f84828501610ad6565b91505092915050565b6000602082019050610b2d6000830184610a2b565b92915050565b60008115159050919050565b610b4881610b33565b82525050565b6000608082019050610b636000830187610a2b565b610b706020830186610b3f565b610b7d6040830185610a95565b610b8a6060830184610a2b565b95945050505050565b6000602082019050610ba86000830184610a1c565b92915050565b600082825260208201905092915050565b7f486173206e6f20726967687420746f20766f7465000000000000000000000000600082015250565b6000610bf5601483610bae565b9150610c0082610bbf565b602082019050919050565b60006020820190508181036000830152610c2481610be8565b9050919050565b7f416c726561647920766f7465642e000000000000000000000000000000000000600082015250565b6000610c61600e83610bae565b9150610c6c82610c2b565b602082019050919050565b60006020820190508181036000830152610c9081610c54565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610d00826109af565b9150610d0b836109af565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610d4057610d3f610cc6565b5b828201905092915050565b7f596f7520616c726561647920766f7465642e0000000000000000000000000000600082015250565b6000610d81601283610bae565b9150610d8c82610d4b565b602082019050919050565b60006020820190508181036000830152610db081610d74565b9050919050565b7f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000600082015250565b6000610ded601e83610bae565b9150610df882610db7565b602082019050919050565b60006020820190508181036000830152610e1c81610de0565b9050919050565b7f466f756e64206c6f6f7020696e2064656c65676174696f6e2e00000000000000600082015250565b6000610e59601983610bae565b9150610e6482610e23565b602082019050919050565b60006020820190508181036000830152610e8881610e4c565b9050919050565b6000610e9a826109af565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610ecd57610ecc610cc6565b5b600182019050919050565b7f4f6e6c79206368616972706572736f6e2063616e20676976652072696768742060008201527f746f20766f74652e000000000000000000000000000000000000000000000000602082015250565b6000610f34602883610bae565b9150610f3f82610ed8565b604082019050919050565b60006020820190508181036000830152610f6381610f27565b9050919050565b7f54686520766f74657220616c726561647920766f7465642e0000000000000000600082015250565b6000610fa0601883610bae565b9150610fab82610f6a565b602082019050919050565b60006020820190508181036000830152610fcf81610f93565b905091905056fea2646970667358221220567adabd19edc7ae85073705af2aa994f6314b7b5debc74f9c25841a1c6bd9e164736f6c637828302e382e31322d646576656c6f702e323032322e312e32302b636f6d6d69742e30623961623333660059", -} - -// BallotABI is the input ABI used to generate the binding from. -// Deprecated: Use BallotMetaData.ABI instead. -var BallotABI = BallotMetaData.ABI - -// BallotBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use BallotMetaData.Bin instead. -var BallotBin = BallotMetaData.Bin - -// DeployBallot deploys a new Ethereum contract, binding an instance of Ballot to it. -func DeployBallot(auth *bind.TransactOpts, backend bind.ContractBackend, proposalNames [][32]byte) (common.Address, *types.Transaction, *Ballot, error) { - parsed, err := BallotMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BallotBin), backend, proposalNames) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Ballot{BallotCaller: BallotCaller{contract: contract}, BallotTransactor: BallotTransactor{contract: contract}, BallotFilterer: BallotFilterer{contract: contract}}, nil -} - -// Ballot is an auto generated Go binding around an Ethereum contract. -type Ballot struct { - BallotCaller // Read-only binding to the contract - BallotTransactor // Write-only binding to the contract - BallotFilterer // Log filterer for contract events -} - -// BallotCaller is an auto generated read-only Go binding around an Ethereum contract. -type BallotCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// BallotTransactor is an auto generated write-only Go binding around an Ethereum contract. -type BallotTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// BallotFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type BallotFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// BallotSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type BallotSession struct { - Contract *Ballot // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// BallotCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type BallotCallerSession struct { - Contract *BallotCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// BallotTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type BallotTransactorSession struct { - Contract *BallotTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// BallotRaw is an auto generated low-level Go binding around an Ethereum contract. -type BallotRaw struct { - Contract *Ballot // Generic contract binding to access the raw methods on -} - -// BallotCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type BallotCallerRaw struct { - Contract *BallotCaller // Generic read-only contract binding to access the raw methods on -} - -// BallotTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type BallotTransactorRaw struct { - Contract *BallotTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewBallot creates a new instance of Ballot, bound to a specific deployed contract. -func NewBallot(address common.Address, backend bind.ContractBackend) (*Ballot, error) { - contract, err := bindBallot(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Ballot{BallotCaller: BallotCaller{contract: contract}, BallotTransactor: BallotTransactor{contract: contract}, BallotFilterer: BallotFilterer{contract: contract}}, nil -} - -// NewBallotCaller creates a new read-only instance of Ballot, bound to a specific deployed contract. -func NewBallotCaller(address common.Address, caller bind.ContractCaller) (*BallotCaller, error) { - contract, err := bindBallot(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &BallotCaller{contract: contract}, nil -} - -// NewBallotTransactor creates a new write-only instance of Ballot, bound to a specific deployed contract. -func NewBallotTransactor(address common.Address, transactor bind.ContractTransactor) (*BallotTransactor, error) { - contract, err := bindBallot(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &BallotTransactor{contract: contract}, nil -} - -// NewBallotFilterer creates a new log filterer instance of Ballot, bound to a specific deployed contract. -func NewBallotFilterer(address common.Address, filterer bind.ContractFilterer) (*BallotFilterer, error) { - contract, err := bindBallot(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &BallotFilterer{contract: contract}, nil -} - -// bindBallot binds a generic wrapper to an already deployed contract. -func bindBallot(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(BallotABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Ballot *BallotRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Ballot.Contract.BallotCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Ballot *BallotRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Ballot.Contract.BallotTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Ballot *BallotRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Ballot.Contract.BallotTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Ballot *BallotCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Ballot.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Ballot *BallotTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Ballot.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Ballot *BallotTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Ballot.Contract.contract.Transact(opts, method, params...) -} - -// Chairperson is a free data retrieval call binding the contract method 0x2e4176cf. -// -// Solidity: function chairperson() view returns(address) -func (_Ballot *BallotCaller) Chairperson(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Ballot.contract.Call(opts, &out, "chairperson") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Chairperson is a free data retrieval call binding the contract method 0x2e4176cf. -// -// Solidity: function chairperson() view returns(address) -func (_Ballot *BallotSession) Chairperson() (common.Address, error) { - return _Ballot.Contract.Chairperson(&_Ballot.CallOpts) -} - -// Chairperson is a free data retrieval call binding the contract method 0x2e4176cf. -// -// Solidity: function chairperson() view returns(address) -func (_Ballot *BallotCallerSession) Chairperson() (common.Address, error) { - return _Ballot.Contract.Chairperson(&_Ballot.CallOpts) -} - -// Proposals is a free data retrieval call binding the contract method 0x013cf08b. -// -// Solidity: function proposals(uint256 ) view returns(bytes32 name, uint256 voteCount) -func (_Ballot *BallotCaller) Proposals(opts *bind.CallOpts, arg0 *big.Int) (struct { - Name [32]byte - VoteCount *big.Int -}, error) { - var out []interface{} - err := _Ballot.contract.Call(opts, &out, "proposals", arg0) - - outstruct := new(struct { - Name [32]byte - VoteCount *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.Name = *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - outstruct.VoteCount = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// Proposals is a free data retrieval call binding the contract method 0x013cf08b. -// -// Solidity: function proposals(uint256 ) view returns(bytes32 name, uint256 voteCount) -func (_Ballot *BallotSession) Proposals(arg0 *big.Int) (struct { - Name [32]byte - VoteCount *big.Int -}, error) { - return _Ballot.Contract.Proposals(&_Ballot.CallOpts, arg0) -} - -// Proposals is a free data retrieval call binding the contract method 0x013cf08b. -// -// Solidity: function proposals(uint256 ) view returns(bytes32 name, uint256 voteCount) -func (_Ballot *BallotCallerSession) Proposals(arg0 *big.Int) (struct { - Name [32]byte - VoteCount *big.Int -}, error) { - return _Ballot.Contract.Proposals(&_Ballot.CallOpts, arg0) -} - -// Voters is a free data retrieval call binding the contract method 0xa3ec138d. -// -// Solidity: function voters(address ) view returns(uint256 weight, bool voted, address delegate, uint256 vote) -func (_Ballot *BallotCaller) Voters(opts *bind.CallOpts, arg0 common.Address) (struct { - Weight *big.Int - Voted bool - Delegate common.Address - Vote *big.Int -}, error) { - var out []interface{} - err := _Ballot.contract.Call(opts, &out, "voters", arg0) - - outstruct := new(struct { - Weight *big.Int - Voted bool - Delegate common.Address - Vote *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.Weight = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.Voted = *abi.ConvertType(out[1], new(bool)).(*bool) - outstruct.Delegate = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) - outstruct.Vote = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// Voters is a free data retrieval call binding the contract method 0xa3ec138d. -// -// Solidity: function voters(address ) view returns(uint256 weight, bool voted, address delegate, uint256 vote) -func (_Ballot *BallotSession) Voters(arg0 common.Address) (struct { - Weight *big.Int - Voted bool - Delegate common.Address - Vote *big.Int -}, error) { - return _Ballot.Contract.Voters(&_Ballot.CallOpts, arg0) -} - -// Voters is a free data retrieval call binding the contract method 0xa3ec138d. -// -// Solidity: function voters(address ) view returns(uint256 weight, bool voted, address delegate, uint256 vote) -func (_Ballot *BallotCallerSession) Voters(arg0 common.Address) (struct { - Weight *big.Int - Voted bool - Delegate common.Address - Vote *big.Int -}, error) { - return _Ballot.Contract.Voters(&_Ballot.CallOpts, arg0) -} - -// WinnerName is a free data retrieval call binding the contract method 0xe2ba53f0. -// -// Solidity: function winnerName() view returns(bytes32 winnerName_) -func (_Ballot *BallotCaller) WinnerName(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _Ballot.contract.Call(opts, &out, "winnerName") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// WinnerName is a free data retrieval call binding the contract method 0xe2ba53f0. -// -// Solidity: function winnerName() view returns(bytes32 winnerName_) -func (_Ballot *BallotSession) WinnerName() ([32]byte, error) { - return _Ballot.Contract.WinnerName(&_Ballot.CallOpts) -} - -// WinnerName is a free data retrieval call binding the contract method 0xe2ba53f0. -// -// Solidity: function winnerName() view returns(bytes32 winnerName_) -func (_Ballot *BallotCallerSession) WinnerName() ([32]byte, error) { - return _Ballot.Contract.WinnerName(&_Ballot.CallOpts) -} - -// WinningProposal is a free data retrieval call binding the contract method 0x609ff1bd. -// -// Solidity: function winningProposal() view returns(uint256 winningProposal_) -func (_Ballot *BallotCaller) WinningProposal(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Ballot.contract.Call(opts, &out, "winningProposal") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// WinningProposal is a free data retrieval call binding the contract method 0x609ff1bd. -// -// Solidity: function winningProposal() view returns(uint256 winningProposal_) -func (_Ballot *BallotSession) WinningProposal() (*big.Int, error) { - return _Ballot.Contract.WinningProposal(&_Ballot.CallOpts) -} - -// WinningProposal is a free data retrieval call binding the contract method 0x609ff1bd. -// -// Solidity: function winningProposal() view returns(uint256 winningProposal_) -func (_Ballot *BallotCallerSession) WinningProposal() (*big.Int, error) { - return _Ballot.Contract.WinningProposal(&_Ballot.CallOpts) -} - -// Delegate is a paid mutator transaction binding the contract method 0x5c19a95c. -// -// Solidity: function delegate(address to) returns() -func (_Ballot *BallotTransactor) Delegate(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _Ballot.contract.Transact(opts, "delegate", to) -} - -// Delegate is a paid mutator transaction binding the contract method 0x5c19a95c. -// -// Solidity: function delegate(address to) returns() -func (_Ballot *BallotSession) Delegate(to common.Address) (*types.Transaction, error) { - return _Ballot.Contract.Delegate(&_Ballot.TransactOpts, to) -} - -// Delegate is a paid mutator transaction binding the contract method 0x5c19a95c. -// -// Solidity: function delegate(address to) returns() -func (_Ballot *BallotTransactorSession) Delegate(to common.Address) (*types.Transaction, error) { - return _Ballot.Contract.Delegate(&_Ballot.TransactOpts, to) -} - -// GiveRightToVote is a paid mutator transaction binding the contract method 0x9e7b8d61. -// -// Solidity: function giveRightToVote(address voter) returns() -func (_Ballot *BallotTransactor) GiveRightToVote(opts *bind.TransactOpts, voter common.Address) (*types.Transaction, error) { - return _Ballot.contract.Transact(opts, "giveRightToVote", voter) -} - -// GiveRightToVote is a paid mutator transaction binding the contract method 0x9e7b8d61. -// -// Solidity: function giveRightToVote(address voter) returns() -func (_Ballot *BallotSession) GiveRightToVote(voter common.Address) (*types.Transaction, error) { - return _Ballot.Contract.GiveRightToVote(&_Ballot.TransactOpts, voter) -} - -// GiveRightToVote is a paid mutator transaction binding the contract method 0x9e7b8d61. -// -// Solidity: function giveRightToVote(address voter) returns() -func (_Ballot *BallotTransactorSession) GiveRightToVote(voter common.Address) (*types.Transaction, error) { - return _Ballot.Contract.GiveRightToVote(&_Ballot.TransactOpts, voter) -} - -// Vote is a paid mutator transaction binding the contract method 0x0121b93f. -// -// Solidity: function vote(uint256 proposal) returns() -func (_Ballot *BallotTransactor) Vote(opts *bind.TransactOpts, proposal *big.Int) (*types.Transaction, error) { - return _Ballot.contract.Transact(opts, "vote", proposal) -} - -// Vote is a paid mutator transaction binding the contract method 0x0121b93f. -// -// Solidity: function vote(uint256 proposal) returns() -func (_Ballot *BallotSession) Vote(proposal *big.Int) (*types.Transaction, error) { - return _Ballot.Contract.Vote(&_Ballot.TransactOpts, proposal) -} - -// Vote is a paid mutator transaction binding the contract method 0x0121b93f. -// -// Solidity: function vote(uint256 proposal) returns() -func (_Ballot *BallotTransactorSession) Vote(proposal *big.Int) (*types.Transaction, error) { - return _Ballot.Contract.Vote(&_Ballot.TransactOpts, proposal) -} - -// BallotNewProposalIterator is returned from FilterNewProposal and is used to iterate over the raw logs and unpacked data for NewProposal events raised by the Ballot contract. -type BallotNewProposalIterator struct { - Event *BallotNewProposal // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *BallotNewProposalIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(BallotNewProposal) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(BallotNewProposal) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *BallotNewProposalIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *BallotNewProposalIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// BallotNewProposal represents a NewProposal event raised by the Ballot contract. -type BallotNewProposal struct { - From common.Address - Name [32]byte - VoteCount *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterNewProposal is a free log retrieval operation binding the contract event 0x4913a1b403184a1c69ab16947e9f4c7a1e48c069dccde91f2bf550ea77becc5b. -// -// Solidity: event NewProposal(address indexed from, bytes32 name, uint256 voteCount) -func (_Ballot *BallotFilterer) FilterNewProposal(opts *bind.FilterOpts, from []common.Address) (*BallotNewProposalIterator, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - - logs, sub, err := _Ballot.contract.FilterLogs(opts, "NewProposal", fromRule) - if err != nil { - return nil, err - } - return &BallotNewProposalIterator{contract: _Ballot.contract, event: "NewProposal", logs: logs, sub: sub}, nil -} - -// WatchNewProposal is a free log subscription operation binding the contract event 0x4913a1b403184a1c69ab16947e9f4c7a1e48c069dccde91f2bf550ea77becc5b. -// -// Solidity: event NewProposal(address indexed from, bytes32 name, uint256 voteCount) -func (_Ballot *BallotFilterer) WatchNewProposal(opts *bind.WatchOpts, sink chan<- *BallotNewProposal, from []common.Address) (event.Subscription, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - - logs, sub, err := _Ballot.contract.WatchLogs(opts, "NewProposal", fromRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(BallotNewProposal) - if err := _Ballot.contract.UnpackLog(event, "NewProposal", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseNewProposal is a log parse operation binding the contract event 0x4913a1b403184a1c69ab16947e9f4c7a1e48c069dccde91f2bf550ea77becc5b. -// -// Solidity: event NewProposal(address indexed from, bytes32 name, uint256 voteCount) -func (_Ballot *BallotFilterer) ParseNewProposal(log types.Log) (*BallotNewProposal, error) { - event := new(BallotNewProposal) - if err := _Ballot.contract.UnpackLog(event, "NewProposal", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/evm/go-x1/gossip/contract/ballot/Ballot.sol b/evm/go-x1/gossip/contract/ballot/Ballot.sol deleted file mode 100644 index 089b298..0000000 --- a/evm/go-x1/gossip/contract/ballot/Ballot.sol +++ /dev/null @@ -1,156 +0,0 @@ -pragma solidity >=0.4.22; - -/// @title Voting with delegation. -contract Ballot { - // This declares a new complex type which will - // be used for variables later. - // It will represent a single voter. - struct Voter { - uint weight; // weight is accumulated by delegation - bool voted; // if true, that person already voted - address delegate; // person delegated to - uint vote; // index of the voted proposal - } - - // This is a type for a single proposal. - struct Proposal { - bytes32 name; // short name (up to 32 bytes) - uint voteCount; // number of accumulated votes - } - - address public chairperson; - - // This declares a state variable that - // stores a `Voter` struct for each possible address. - mapping(address => Voter) public voters; - - // A dynamically-sized array of `Proposal` structs. - Proposal[] public proposals; - - // Emit event - event NewProposal(address indexed from, bytes32 name, uint voteCount); - - /// Create a new ballot to choose one of `proposalNames`. - constructor(bytes32[] memory proposalNames) public { - chairperson = msg.sender; - voters[chairperson].weight = 1; - - // For each of the provided proposal names, - // create a new proposal object and add it - // to the end of the array. - for (uint i = 0; i < proposalNames.length; i++) { - // `Proposal({...})` creates a temporary - // Proposal object and `proposals.push(...)` - // appends it to the end of `proposals`. - proposals.push(Proposal({ - name: proposalNames[i], - voteCount: 0 - })); - - emit NewProposal(msg.sender, proposalNames[i], 0); - } - } - - // Give `voter` the right to vote on this ballot. - // May only be called by `chairperson`. - function giveRightToVote(address voter) public { - // If the first argument of `require` evaluates - // to `false`, execution terminates and all - // changes to the state and to Ether balances - // are reverted. - // This used to consume all gas in old EVM versions, but - // not anymore. - // It is often a good idea to use `require` to check if - // functions are called correctly. - // As a second argument, you can also provide an - // explanation about what went wrong. - require( - msg.sender == chairperson, - "Only chairperson can give right to vote." - ); - require( - !voters[voter].voted, - "The voter already voted." - ); - require(voters[voter].weight == 0); - voters[voter].weight = 1; - } - - /// Delegate your vote to the voter `to`. - function delegate(address to) public { - // assigns reference - Voter storage sender = voters[msg.sender]; - require(!sender.voted, "You already voted."); - - require(to != msg.sender, "Self-delegation is disallowed."); - - // Forward the delegation as long as - // `to` also delegated. - // In general, such loops are very dangerous, - // because if they run too long, they might - // need more gas than is available in a block. - // In this case, the delegation will not be executed, - // but in other situations, such loops might - // cause a contract to get "stuck" completely. - while (voters[to].delegate != address(0)) { - to = voters[to].delegate; - - // We found a loop in the delegation, not allowed. - require(to != msg.sender, "Found loop in delegation."); - } - - // Since `sender` is a reference, this - // modifies `voters[msg.sender].voted` - sender.voted = true; - sender.delegate = to; - Voter storage delegate_ = voters[to]; - if (delegate_.voted) { - // If the delegate already voted, - // directly add to the number of votes - proposals[delegate_.vote].voteCount += sender.weight; - } else { - // If the delegate did not vote yet, - // add to her weight. - delegate_.weight += sender.weight; - } - } - - /// Give your vote (including votes delegated to you) - /// to proposal `proposals[proposal].name`. - function vote(uint proposal) public { - Voter storage sender = voters[msg.sender]; - require(sender.weight != 0, "Has no right to vote"); - require(!sender.voted, "Already voted."); - sender.voted = true; - sender.vote = proposal; - - // If `proposal` is out of the range of the array, - // this will throw automatically and revert all - // changes. - proposals[proposal].voteCount += sender.weight; - } - - /// @dev Computes the winning proposal taking all - /// previous votes into account. - function winningProposal() public view - returns (uint winningProposal_) - { - uint winningVoteCount = 0; - for (uint p = 0; p < proposals.length; p++) { - if (proposals[p].voteCount > winningVoteCount) { - winningVoteCount = proposals[p].voteCount; - winningProposal_ = p; - } - } - } - - // Calls winningProposal() function to get the index - // of the winner contained in the proposals array and then - // returns the name of the winner - function winnerName() public view - returns (bytes32 winnerName_) - { - winnerName_ = proposals[winningProposal()].name; - } -} - diff --git a/evm/go-x1/gossip/contract/ballot/ballot.abi b/evm/go-x1/gossip/contract/ballot/ballot.abi deleted file mode 100644 index 3b163ec..0000000 --- a/evm/go-x1/gossip/contract/ballot/ballot.abi +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"bytes32[]","name":"proposalNames","type":"bytes32[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"voteCount","type":"uint256"}],"name":"NewProposal","type":"event"},{"inputs":[],"name":"chairperson","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"voter","type":"address"}],"name":"giveRightToVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"bytes32","name":"name","type":"bytes32"},{"internalType":"uint256","name":"voteCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposal","type":"uint256"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"voters","outputs":[{"internalType":"uint256","name":"weight","type":"uint256"},{"internalType":"bool","name":"voted","type":"bool"},{"internalType":"address","name":"delegate","type":"address"},{"internalType":"uint256","name":"vote","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"winnerName","outputs":[{"internalType":"bytes32","name":"winnerName_","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"winningProposal","outputs":[{"internalType":"uint256","name":"winningProposal_","type":"uint256"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/evm/go-x1/gossip/contract/ballot/ballot.bin b/evm/go-x1/gossip/contract/ballot/ballot.bin deleted file mode 100644 index ce2c335..0000000 --- a/evm/go-x1/gossip/contract/ballot/ballot.bin +++ /dev/null @@ -1 +0,0 @@ -60806040523480156200001157600080fd5b5060405162001586380380620015868339818101604052810190620000379190620003b2565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555060005b8151811015620001e657600260405180604001604052808484815181106200010f576200010e62000403565b5b6020026020010151815260200160008152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550503373ffffffffffffffffffffffffffffffffffffffff167f4913a1b403184a1c69ab16947e9f4c7a1e48c069dccde91f2bf550ea77becc5b838381518110620001ae57620001ad62000403565b5b60200260200101516000604051620001c89291906200049a565b60405180910390a28080620001dd90620004f6565b915050620000e2565b505062000544565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620002528262000207565b810181811067ffffffffffffffff8211171562000274576200027362000218565b5b80604052505050565b600062000289620001ee565b905062000297828262000247565b919050565b600067ffffffffffffffff821115620002ba57620002b962000218565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b620002e581620002d0565b8114620002f157600080fd5b50565b6000815190506200030581620002da565b92915050565b6000620003226200031c846200029c565b6200027d565b90508083825260208201905060208402830185811115620003485762000347620002cb565b5b835b81811015620003755780620003608882620002f4565b8452602084019350506020810190506200034a565b5050509392505050565b600082601f83011262000397576200039662000202565b5b8151620003a98482602086016200030b565b91505092915050565b600060208284031215620003cb57620003ca620001f8565b5b600082015167ffffffffffffffff811115620003ec57620003eb620001fd565b5b620003fa848285016200037f565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6200043d81620002d0565b82525050565b6000819050919050565b6000819050919050565b6000819050919050565b6000620004826200047c620004768462000443565b62000457565b6200044d565b9050919050565b620004948162000461565b82525050565b6000604082019050620004b1600083018562000432565b620004c0602083018462000489565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000503826200044d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415620005395762000538620004c7565b5b600182019050919050565b61103280620005546000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063609ff1bd1161005b578063609ff1bd146101145780639e7b8d6114610132578063a3ec138d1461014e578063e2ba53f01461018157610088565b80630121b93f1461008d578063013cf08b146100a95780632e4176cf146100da5780635c19a95c146100f8575b600080fd5b6100a760048036038101906100a291906109e5565b61019f565b005b6100c360048036038101906100be91906109e5565b6102e6565b6040516100d1929190610a3a565b60405180910390f35b6100e261031a565b6040516100ef9190610aa4565b60405180910390f35b610112600480360381019061010d9190610aeb565b61033e565b005b61011c6106da565b6040516101299190610b18565b60405180910390f35b61014c60048036038101906101479190610aeb565b610762565b005b61016860048036038101906101639190610aeb565b610919565b6040516101789493929190610b4e565b60405180910390f35b610189610976565b6040516101969190610b93565b60405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561022a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022190610c0b565b60405180910390fd5b8060010160009054906101000a900460ff161561027c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027390610c77565b60405180910390fd5b60018160010160006101000a81548160ff0219169083151502179055508181600201819055508060000154600283815481106102bb576102ba610c97565b5b906000526020600020906002020160010160008282546102db9190610cf5565b925050819055505050565b600281815481106102f657600080fd5b90600052602060002090600202016000915090508060000154908060010154905082565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156103d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ca90610d97565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043990610e03565b60405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146105b257600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156105ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a490610e6f565b60405180910390fd5b610443565b60018160010160006101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156106b5578160000154600282600201548154811061068957610688610c97565b5b906000526020600020906002020160010160008282546106a99190610cf5565b925050819055506106d5565b81600001548160000160008282546106cd9190610cf5565b925050819055505b505050565b6000806000905060005b60028054905081101561075d57816002828154811061070657610705610c97565b5b906000526020600020906002020160010154111561074a576002818154811061073257610731610c97565b5b90600052602060002090600202016001015491508092505b808061075590610e8f565b9150506106e4565b505090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e790610f4a565b60405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1615610880576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087790610fb6565b60405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154146108cf57600080fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b600060026109826106da565b8154811061099357610992610c97565b5b906000526020600020906002020160000154905090565b600080fd5b6000819050919050565b6109c2816109af565b81146109cd57600080fd5b50565b6000813590506109df816109b9565b92915050565b6000602082840312156109fb576109fa6109aa565b5b6000610a09848285016109d0565b91505092915050565b6000819050919050565b610a2581610a12565b82525050565b610a34816109af565b82525050565b6000604082019050610a4f6000830185610a1c565b610a5c6020830184610a2b565b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610a8e82610a63565b9050919050565b610a9e81610a83565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b610ac881610a83565b8114610ad357600080fd5b50565b600081359050610ae581610abf565b92915050565b600060208284031215610b0157610b006109aa565b5b6000610b0f84828501610ad6565b91505092915050565b6000602082019050610b2d6000830184610a2b565b92915050565b60008115159050919050565b610b4881610b33565b82525050565b6000608082019050610b636000830187610a2b565b610b706020830186610b3f565b610b7d6040830185610a95565b610b8a6060830184610a2b565b95945050505050565b6000602082019050610ba86000830184610a1c565b92915050565b600082825260208201905092915050565b7f486173206e6f20726967687420746f20766f7465000000000000000000000000600082015250565b6000610bf5601483610bae565b9150610c0082610bbf565b602082019050919050565b60006020820190508181036000830152610c2481610be8565b9050919050565b7f416c726561647920766f7465642e000000000000000000000000000000000000600082015250565b6000610c61600e83610bae565b9150610c6c82610c2b565b602082019050919050565b60006020820190508181036000830152610c9081610c54565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610d00826109af565b9150610d0b836109af565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610d4057610d3f610cc6565b5b828201905092915050565b7f596f7520616c726561647920766f7465642e0000000000000000000000000000600082015250565b6000610d81601283610bae565b9150610d8c82610d4b565b602082019050919050565b60006020820190508181036000830152610db081610d74565b9050919050565b7f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000600082015250565b6000610ded601e83610bae565b9150610df882610db7565b602082019050919050565b60006020820190508181036000830152610e1c81610de0565b9050919050565b7f466f756e64206c6f6f7020696e2064656c65676174696f6e2e00000000000000600082015250565b6000610e59601983610bae565b9150610e6482610e23565b602082019050919050565b60006020820190508181036000830152610e8881610e4c565b9050919050565b6000610e9a826109af565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610ecd57610ecc610cc6565b5b600182019050919050565b7f4f6e6c79206368616972706572736f6e2063616e20676976652072696768742060008201527f746f20766f74652e000000000000000000000000000000000000000000000000602082015250565b6000610f34602883610bae565b9150610f3f82610ed8565b604082019050919050565b60006020820190508181036000830152610f6381610f27565b9050919050565b7f54686520766f74657220616c726561647920766f7465642e0000000000000000600082015250565b6000610fa0601883610bae565b9150610fab82610f6a565b602082019050919050565b60006020820190508181036000830152610fcf81610f93565b905091905056fea2646970667358221220567adabd19edc7ae85073705af2aa994f6314b7b5debc74f9c25841a1c6bd9e164736f6c637828302e382e31322d646576656c6f702e323032322e312e32302b636f6d6d69742e30623961623333660059 diff --git a/evm/go-x1/gossip/contract/contract.go b/evm/go-x1/gossip/contract/contract.go deleted file mode 100644 index 21b330f..0000000 --- a/evm/go-x1/gossip/contract/contract.go +++ /dev/null @@ -1,458 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package ballot - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// ContractMetaData contains all meta data concerning the Contract contract. -var ContractMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposalNames\",\"type\":\"bytes32[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"constant\":true,\"inputs\":[],\"name\":\"chairperson\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"voter\",\"type\":\"address\"}],\"name\":\"giveRightToVote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"proposals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"voteCount\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"proposal\",\"type\":\"uint256\"}],\"name\":\"vote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"voters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"vote\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"winnerName\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"winnerName_\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"winningProposal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningProposal_\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5060405161089a38038061089a8339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825186602082028301116401000000008211171561008557600080fd5b82525081516020918201928201910280838360005b838110156100b257818101518382015260200161009a565b50505050919091016040908152600080546001600160a01b03191633178082556001600160a01b03168152600160208190529181209190915593505050505b8151811015610153576002604051806040016040528084848151811061011357fe5b60209081029190910181015182526000918101829052835460018181018655948352918190208351600290930201918255919091015190820155016100f1565b5050610736806101646000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063609ff1bd1161005b578063609ff1bd1461012c5780639e7b8d6114610146578063a3ec138d1461016c578063e2ba53f0146101c057610088565b80630121b93f1461008d578063013cf08b146100ac5780632e4176cf146100e25780635c19a95c14610106575b600080fd5b6100aa600480360360208110156100a357600080fd5b50356101c8565b005b6100c9600480360360208110156100c257600080fd5b50356102cb565b6040805192835260208301919091528051918290030190f35b6100ea6102f6565b604080516001600160a01b039092168252519081900360200190f35b6100aa6004803603602081101561011c57600080fd5b50356001600160a01b0316610305565b610134610516565b60408051918252519081900360200190f35b6100aa6004803603602081101561015c57600080fd5b50356001600160a01b031661057d565b6101926004803603602081101561018257600080fd5b50356001600160a01b0316610678565b6040805194855292151560208501526001600160a01b03909116838301526060830152519081900360800190f35b6101346106ac565b336000908152600160205260409020805461022a576040805162461bcd60e51b815260206004820152601460248201527f486173206e6f20726967687420746f20766f7465000000000000000000000000604482015290519081900360640190fd5b600181015460ff1615610284576040805162461bcd60e51b815260206004820152600e60248201527f416c726561647920766f7465642e000000000000000000000000000000000000604482015290519081900360640190fd5b6001818101805460ff19169091179055600280820183905581548154909190849081106102ad57fe5b60009182526020909120600160029092020101805490910190555050565b600281815481106102d857fe5b60009182526020909120600290910201805460019091015490915082565b6000546001600160a01b031681565b3360009081526001602081905260409091209081015460ff1615610370576040805162461bcd60e51b815260206004820152601260248201527f596f7520616c726561647920766f7465642e0000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b0382163314156103ce576040805162461bcd60e51b815260206004820152601e60248201527f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000604482015290519081900360640190fd5b6001600160a01b038281166000908152600160208190526040909120015461010090041615610478576001600160a01b039182166000908152600160208190526040909120015461010090049091169033821415610473576040805162461bcd60e51b815260206004820152601960248201527f466f756e64206c6f6f7020696e2064656c65676174696f6e2e00000000000000604482015290519081900360640190fd5b6103ce565b6001818101805460ff191682177fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b0386169081029190911790915560009081526020829052604090209081015460ff1615610509578154600282810154815481106104ea57fe5b6000918252602090912060016002909202010180549091019055610511565b815481540181555b505050565b600080805b60025481101561057857816002828154811061053357fe5b9060005260206000209060020201600101541115610570576002818154811061055857fe5b90600052602060002090600202016001015491508092505b60010161051b565b505090565b6000546001600160a01b031633146105c65760405162461bcd60e51b81526004018080602001828103825260288152602001806106da6028913960400191505060405180910390fd5b6001600160a01b0381166000908152600160208190526040909120015460ff1615610638576040805162461bcd60e51b815260206004820152601860248201527f54686520766f74657220616c726561647920766f7465642e0000000000000000604482015290519081900360640190fd5b6001600160a01b0381166000908152600160205260409020541561065b57600080fd5b6001600160a01b0316600090815260016020819052604090912055565b600160208190526000918252604090912080549181015460029091015460ff82169161010090046001600160a01b03169084565b600060026106b8610516565b815481106106c257fe5b90600052602060002090600202016000015490509056fe4f6e6c79206368616972706572736f6e2063616e206769766520726967687420746f20766f74652ea265627a7a72315820a22e04a1172617645f3654f281b81f779805de1b7d7930b30443c2f276926a8564736f6c634300050c0032", -} - -// ContractABI is the input ABI used to generate the binding from. -// Deprecated: Use ContractMetaData.ABI instead. -var ContractABI = ContractMetaData.ABI - -// ContractBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ContractMetaData.Bin instead. -var ContractBin = ContractMetaData.Bin - -// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. -func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend, proposalNames [][32]byte) (common.Address, *types.Transaction, *Contract, error) { - parsed, err := ContractMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend, proposalNames) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// Contract is an auto generated Go binding around an Ethereum contract. -type Contract struct { - ContractCaller // Read-only binding to the contract - ContractTransactor // Write-only binding to the contract - ContractFilterer // Log filterer for contract events -} - -// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. -type ContractCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ContractTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ContractFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ContractSession struct { - Contract *Contract // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ContractCallerSession struct { - Contract *ContractCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ContractTransactorSession struct { - Contract *ContractTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. -type ContractRaw struct { - Contract *Contract // Generic contract binding to access the raw methods on -} - -// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ContractCallerRaw struct { - Contract *ContractCaller // Generic read-only contract binding to access the raw methods on -} - -// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ContractTransactorRaw struct { - Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewContract creates a new instance of Contract, bound to a specific deployed contract. -func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { - contract, err := bindContract(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. -func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { - contract, err := bindContract(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ContractCaller{contract: contract}, nil -} - -// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. -func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { - contract, err := bindContract(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ContractTransactor{contract: contract}, nil -} - -// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. -func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { - contract, err := bindContract(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ContractFilterer{contract: contract}, nil -} - -// bindContract binds a generic wrapper to an already deployed contract. -func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ContractABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.contract.Transact(opts, method, params...) -} - -// Chairperson is a free data retrieval call binding the contract method 0x2e4176cf. -// -// Solidity: function chairperson() view returns(address) -func (_Contract *ContractCaller) Chairperson(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "chairperson") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Chairperson is a free data retrieval call binding the contract method 0x2e4176cf. -// -// Solidity: function chairperson() view returns(address) -func (_Contract *ContractSession) Chairperson() (common.Address, error) { - return _Contract.Contract.Chairperson(&_Contract.CallOpts) -} - -// Chairperson is a free data retrieval call binding the contract method 0x2e4176cf. -// -// Solidity: function chairperson() view returns(address) -func (_Contract *ContractCallerSession) Chairperson() (common.Address, error) { - return _Contract.Contract.Chairperson(&_Contract.CallOpts) -} - -// Proposals is a free data retrieval call binding the contract method 0x013cf08b. -// -// Solidity: function proposals(uint256 ) view returns(bytes32 name, uint256 voteCount) -func (_Contract *ContractCaller) Proposals(opts *bind.CallOpts, arg0 *big.Int) (struct { - Name [32]byte - VoteCount *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "proposals", arg0) - - outstruct := new(struct { - Name [32]byte - VoteCount *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.Name = *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - outstruct.VoteCount = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// Proposals is a free data retrieval call binding the contract method 0x013cf08b. -// -// Solidity: function proposals(uint256 ) view returns(bytes32 name, uint256 voteCount) -func (_Contract *ContractSession) Proposals(arg0 *big.Int) (struct { - Name [32]byte - VoteCount *big.Int -}, error) { - return _Contract.Contract.Proposals(&_Contract.CallOpts, arg0) -} - -// Proposals is a free data retrieval call binding the contract method 0x013cf08b. -// -// Solidity: function proposals(uint256 ) view returns(bytes32 name, uint256 voteCount) -func (_Contract *ContractCallerSession) Proposals(arg0 *big.Int) (struct { - Name [32]byte - VoteCount *big.Int -}, error) { - return _Contract.Contract.Proposals(&_Contract.CallOpts, arg0) -} - -// Voters is a free data retrieval call binding the contract method 0xa3ec138d. -// -// Solidity: function voters(address ) view returns(uint256 weight, bool voted, address delegate, uint256 vote) -func (_Contract *ContractCaller) Voters(opts *bind.CallOpts, arg0 common.Address) (struct { - Weight *big.Int - Voted bool - Delegate common.Address - Vote *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "voters", arg0) - - outstruct := new(struct { - Weight *big.Int - Voted bool - Delegate common.Address - Vote *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.Weight = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.Voted = *abi.ConvertType(out[1], new(bool)).(*bool) - outstruct.Delegate = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) - outstruct.Vote = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// Voters is a free data retrieval call binding the contract method 0xa3ec138d. -// -// Solidity: function voters(address ) view returns(uint256 weight, bool voted, address delegate, uint256 vote) -func (_Contract *ContractSession) Voters(arg0 common.Address) (struct { - Weight *big.Int - Voted bool - Delegate common.Address - Vote *big.Int -}, error) { - return _Contract.Contract.Voters(&_Contract.CallOpts, arg0) -} - -// Voters is a free data retrieval call binding the contract method 0xa3ec138d. -// -// Solidity: function voters(address ) view returns(uint256 weight, bool voted, address delegate, uint256 vote) -func (_Contract *ContractCallerSession) Voters(arg0 common.Address) (struct { - Weight *big.Int - Voted bool - Delegate common.Address - Vote *big.Int -}, error) { - return _Contract.Contract.Voters(&_Contract.CallOpts, arg0) -} - -// WinnerName is a free data retrieval call binding the contract method 0xe2ba53f0. -// -// Solidity: function winnerName() view returns(bytes32 winnerName_) -func (_Contract *ContractCaller) WinnerName(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "winnerName") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// WinnerName is a free data retrieval call binding the contract method 0xe2ba53f0. -// -// Solidity: function winnerName() view returns(bytes32 winnerName_) -func (_Contract *ContractSession) WinnerName() ([32]byte, error) { - return _Contract.Contract.WinnerName(&_Contract.CallOpts) -} - -// WinnerName is a free data retrieval call binding the contract method 0xe2ba53f0. -// -// Solidity: function winnerName() view returns(bytes32 winnerName_) -func (_Contract *ContractCallerSession) WinnerName() ([32]byte, error) { - return _Contract.Contract.WinnerName(&_Contract.CallOpts) -} - -// WinningProposal is a free data retrieval call binding the contract method 0x609ff1bd. -// -// Solidity: function winningProposal() view returns(uint256 winningProposal_) -func (_Contract *ContractCaller) WinningProposal(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "winningProposal") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// WinningProposal is a free data retrieval call binding the contract method 0x609ff1bd. -// -// Solidity: function winningProposal() view returns(uint256 winningProposal_) -func (_Contract *ContractSession) WinningProposal() (*big.Int, error) { - return _Contract.Contract.WinningProposal(&_Contract.CallOpts) -} - -// WinningProposal is a free data retrieval call binding the contract method 0x609ff1bd. -// -// Solidity: function winningProposal() view returns(uint256 winningProposal_) -func (_Contract *ContractCallerSession) WinningProposal() (*big.Int, error) { - return _Contract.Contract.WinningProposal(&_Contract.CallOpts) -} - -// Delegate is a paid mutator transaction binding the contract method 0x5c19a95c. -// -// Solidity: function delegate(address to) returns() -func (_Contract *ContractTransactor) Delegate(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "delegate", to) -} - -// Delegate is a paid mutator transaction binding the contract method 0x5c19a95c. -// -// Solidity: function delegate(address to) returns() -func (_Contract *ContractSession) Delegate(to common.Address) (*types.Transaction, error) { - return _Contract.Contract.Delegate(&_Contract.TransactOpts, to) -} - -// Delegate is a paid mutator transaction binding the contract method 0x5c19a95c. -// -// Solidity: function delegate(address to) returns() -func (_Contract *ContractTransactorSession) Delegate(to common.Address) (*types.Transaction, error) { - return _Contract.Contract.Delegate(&_Contract.TransactOpts, to) -} - -// GiveRightToVote is a paid mutator transaction binding the contract method 0x9e7b8d61. -// -// Solidity: function giveRightToVote(address voter) returns() -func (_Contract *ContractTransactor) GiveRightToVote(opts *bind.TransactOpts, voter common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "giveRightToVote", voter) -} - -// GiveRightToVote is a paid mutator transaction binding the contract method 0x9e7b8d61. -// -// Solidity: function giveRightToVote(address voter) returns() -func (_Contract *ContractSession) GiveRightToVote(voter common.Address) (*types.Transaction, error) { - return _Contract.Contract.GiveRightToVote(&_Contract.TransactOpts, voter) -} - -// GiveRightToVote is a paid mutator transaction binding the contract method 0x9e7b8d61. -// -// Solidity: function giveRightToVote(address voter) returns() -func (_Contract *ContractTransactorSession) GiveRightToVote(voter common.Address) (*types.Transaction, error) { - return _Contract.Contract.GiveRightToVote(&_Contract.TransactOpts, voter) -} - -// Vote is a paid mutator transaction binding the contract method 0x0121b93f. -// -// Solidity: function vote(uint256 proposal) returns() -func (_Contract *ContractTransactor) Vote(opts *bind.TransactOpts, proposal *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "vote", proposal) -} - -// Vote is a paid mutator transaction binding the contract method 0x0121b93f. -// -// Solidity: function vote(uint256 proposal) returns() -func (_Contract *ContractSession) Vote(proposal *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Vote(&_Contract.TransactOpts, proposal) -} - -// Vote is a paid mutator transaction binding the contract method 0x0121b93f. -// -// Solidity: function vote(uint256 proposal) returns() -func (_Contract *ContractTransactorSession) Vote(proposal *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Vote(&_Contract.TransactOpts, proposal) -} diff --git a/evm/go-x1/gossip/contract/driver100/contract.go b/evm/go-x1/gossip/contract/driver100/contract.go deleted file mode 100644 index 1a0acce..0000000 --- a/evm/go-x1/gossip/contract/driver100/contract.go +++ /dev/null @@ -1,1418 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package driver100 - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// ContractMetaData contains all meta data concerning the Contract contract. -var ContractMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"num\",\"type\":\"uint256\"}],\"name\":\"AdvanceEpochs\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"diff\",\"type\":\"bytes\"}],\"name\":\"UpdateNetworkRules\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"UpdateNetworkVersion\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"}],\"name\":\"UpdateValidatorPubkey\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"name\":\"UpdateValidatorWeight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"backend\",\"type\":\"address\"}],\"name\":\"UpdatedBackend\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_backend\",\"type\":\"address\"}],\"name\":\"setBackend\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_backend\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_evmWriterAddress\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"copyCode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"with\",\"type\":\"address\"}],\"name\":\"swapCode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"value\",\"type\":\"bytes32\"}],\"name\":\"setStorage\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"diff\",\"type\":\"uint256\"}],\"name\":\"incNonce\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"diff\",\"type\":\"bytes\"}],\"name\":\"updateNetworkRules\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateNetworkVersion\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"num\",\"type\":\"uint256\"}],\"name\":\"advanceEpochs\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"updateValidatorWeight\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"}],\"name\":\"updateValidatorPubkey\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_auth\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedTime\",\"type\":\"uint256\"}],\"name\":\"setGenesisValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockedStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupFromEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupEndTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyUnlockPenalty\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"}],\"name\":\"setGenesisDelegation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"}],\"name\":\"deactivateValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nextValidatorIDs\",\"type\":\"uint256[]\"}],\"name\":\"sealEpochValidators\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"offlineTimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"offlineBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"uptimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"originatedTxsFee\",\"type\":\"uint256[]\"}],\"name\":\"sealEpoch\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"offlineTimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"offlineBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"uptimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"originatedTxsFee\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"usedGas\",\"type\":\"uint256\"}],\"name\":\"sealEpochV1\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50611b5e806100206000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806379bead38116100b2578063d6a0c7af11610081578063e08d7e6611610066578063e08d7e6614610676578063e30443bc146106e6578063ebdf104c1461071f57610136565b8063d6a0c7af14610608578063da7fc24f1461064357610136565b806379bead38146103d65780637f52e13e1461040f578063a4066fbe14610575578063b9cc6b1c1461059857610136565b8063242a6e3f1161010957806339e503ab116100ee57806339e503ab146102b1578063485cc955146102f05780634feb92f31461032b57610136565b8063242a6e3f1461021d578063267ab4461461029457610136565b806307690b2a1461013b5780630aeeca001461017857806318f628d4146101955780631e702f83146101fa575b600080fd5b6101766004803603604081101561015157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610885565b005b6101766004803603602081101561018e57600080fd5b5035610989565b61017660048036036101208110156101ac57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e0810135906101000135610a2b565b6101766004803603604081101561021057600080fd5b5080359060200135610b4f565b6101766004803603604081101561023357600080fd5b8135919081019060408101602082013564010000000081111561025557600080fd5b82018360208201111561026757600080fd5b8035906020019184600183028401116401000000008311171561028957600080fd5b509092509050610c1c565b610176600480360360208110156102aa57600080fd5b5035610cee565b610176600480360360608110156102c757600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060208101359060400135610d90565b6101766004803603604081101561030657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610e9b565b610176600480360361010081101561034257600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b919350915080359060208101359060408101359060608101359060800135611043565b610176600480360360408110156103ec57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561119b565b610176600480360360a081101561042557600080fd5b81019060208101813564010000000081111561044057600080fd5b82018360208201111561045257600080fd5b8035906020019184602083028401116401000000008311171561047457600080fd5b91939092909160208101903564010000000081111561049257600080fd5b8201836020820111156104a457600080fd5b803590602001918460208302840111640100000000831117156104c657600080fd5b9193909290916020810190356401000000008111156104e457600080fd5b8201836020820111156104f657600080fd5b8035906020019184602083028401116401000000008311171561051857600080fd5b91939092909160208101903564010000000081111561053657600080fd5b82018360208201111561054857600080fd5b8035906020019184602083028401116401000000008311171561056a57600080fd5b919350915035611282565b6101766004803603604081101561058b57600080fd5b5080359060200135611411565b610176600480360360208110156105ae57600080fd5b8101906020810181356401000000008111156105c957600080fd5b8201836020820111156105db57600080fd5b803590602001918460018302840111640100000000831117156105fd57600080fd5b5090925090506114b7565b6101766004803603604081101561061e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516611587565b6101766004803603602081101561065957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661166f565b6101766004803603602081101561068c57600080fd5b8101906020810181356401000000008111156106a757600080fd5b8201836020820111156106b957600080fd5b803590602001918460208302840111640100000000831117156106db57600080fd5b509092509050611763565b610176600480360360408110156106fc57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611859565b6101766004803603608081101561073557600080fd5b81019060208101813564010000000081111561075057600080fd5b82018360208201111561076257600080fd5b8035906020019184602083028401116401000000008311171561078457600080fd5b9193909290916020810190356401000000008111156107a257600080fd5b8201836020820111156107b457600080fd5b803590602001918460208302840111640100000000831117156107d657600080fd5b9193909290916020810190356401000000008111156107f457600080fd5b82018360208201111561080657600080fd5b8035906020019184602083028401116401000000008311171561082857600080fd5b91939092909160208101903564010000000081111561084657600080fd5b82018360208201111561085857600080fd5b8035906020019184602083028401116401000000008311171561087a57600080fd5b509092509050611940565b60345473ffffffffffffffffffffffffffffffffffffffff1633146108f1576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517f07690b2a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528481166024830152915191909216916307690b2a91604480830192600092919082900301818387803b15801561096d57600080fd5b505af1158015610981573d6000803e3d6000fd5b505050505050565b60345473ffffffffffffffffffffffffffffffffffffffff1633146109f5576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b6040805182815290517f0151256d62457b809bbc891b1f81c6dd0b9987552c70ce915b519750cd434dd19181900360200190a150565b3315610a7e576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603454604080517f18f628d400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c9052604482018b9052606482018a90526084820189905260a4820188905260c4820187905260e482018690526101048201859052915191909216916318f628d49161012480830192600092919082900301818387803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b50505050505050505050505050565b3315610ba2576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603454604080517f1e702f830000000000000000000000000000000000000000000000000000000081526004810185905260248101849052905173ffffffffffffffffffffffffffffffffffffffff90921691631e702f839160448082019260009290919082900301818387803b15801561096d57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff163314610c88576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b827f0f0ef1ab97439def0a9d2c6d9dc166207f1b13b99e62b442b2993d6153c63a6e838360405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2505050565b60345473ffffffffffffffffffffffffffffffffffffffff163314610d5a576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b6040805182815290517f2ccdfd47cf0c1f1069d949f1789bb79b2f12821f021634fc835af1de66ea2feb9181900360200190a150565b60345473ffffffffffffffffffffffffffffffffffffffff163314610dfc576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517f39e503ab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301526024820186905260448201859052915191909216916339e503ab91606480830192600092919082900301818387803b158015610e7e57600080fd5b505af1158015610e92573d6000803e3d6000fd5b50505050505050565b600054610100900460ff1680610eb45750610eb4611af5565b80610ec2575060005460ff16155b610efd5760405162461bcd60e51b815260040180806020018281038252602e815260200180611afc602e913960400191505060405180910390fd5b600054610100900460ff16158015610f6357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85169081179091556040517f64ee8f7bfc37fc205d7194ee3d64947ab7b57e663cd0d1abd3ef24503583069390600090a2603580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561103e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b505050565b3315611096576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634feb92f38a8a8a8a8a8a8a8a8a6040518a63ffffffff1660e01b8152600401808a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001898152602001806020018781526020018681526020018581526020018481526020018381526020018281038252898982818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b158015610b2c57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff163314611207576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517f79bead3800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260248201859052915191909216916379bead3891604480830192600092919082900301818387803b15801561096d57600080fd5b33156112d5576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663592fe0c08a8a8a8a8a8a8a8a8a6040518a63ffffffff1660e01b8152600401808060200180602001806020018060200186815260200185810385528e8e82818152602001925060200280828437600083820152601f01601f191690910186810385528c8152602090810191508d908d0280828437600083820152601f01601f191690910186810384528a8152602090810191508b908b0280828437600083820152601f01601f19169091018681038352888152602090810191508990890280828437600081840152601f19601f8201169050808301925050509d5050505050505050505050505050600060405180830381600087803b158015610b2c57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff16331461147d576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b60408051828152905183917fb975807576e3b1461be7de07ebf7d20e4790ed802d7a0c4fdd0a1a13df72a935919081900360200190a25050565b60345473ffffffffffffffffffffffffffffffffffffffff163314611523576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b7f47d10eed096a44e3d0abc586c7e3a5d6cb5358cc90e7d437cd0627f7e765fb99828260405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a15050565b60345473ffffffffffffffffffffffffffffffffffffffff1633146115f3576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517fd6a0c7af00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015284811660248301529151919092169163d6a0c7af91604480830192600092919082900301818387803b15801561096d57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff1633146116db576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b60405173ffffffffffffffffffffffffffffffffffffffff8216907f64ee8f7bfc37fc205d7194ee3d64947ab7b57e663cd0d1abd3ef24503583069390600090a2603480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b33156117b6576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b6034546040517fe08d7e660000000000000000000000000000000000000000000000000000000081526020600482018181526024830185905273ffffffffffffffffffffffffffffffffffffffff9093169263e08d7e6692869286929182916044909101908590850280828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b15801561096d57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff1633146118c5576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517fe30443bc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590529151919092169163e30443bc91604480830192600092919082900301818387803b15801561096d57600080fd5b3315611993576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663592fe0c0898989898989898963322adc3a6040518a63ffffffff1660e01b8152600401808060200180602001806020018060200186815260200185810385528e8e82818152602001925060200280828437600083820152601f01601f191690910186810385528c8152602090810191508d908d0280828437600083820152601f01601f191690910186810384528a8152602090810191508b908b0280828437600083820152601f01601f19169091018681038352888152602090810191508990890280828437600081840152601f19601f8201169050808301925050509d5050505050505050505050505050600060405180830381600087803b158015611ad357600080fd5b505af1158015611ae7573d6000803e3d6000fd5b505050505050505050505050565b303b159056fe436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a265627a7a72315820f5cb1667fae9152cab345389c6f9b54dccee170ca51c179d91361997f298acf464736f6c63430005110032", -} - -// ContractABI is the input ABI used to generate the binding from. -// Deprecated: Use ContractMetaData.ABI instead. -var ContractABI = ContractMetaData.ABI - -// ContractBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ContractMetaData.Bin instead. -var ContractBin = ContractMetaData.Bin - -// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. -func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Contract, error) { - parsed, err := ContractMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// Contract is an auto generated Go binding around an Ethereum contract. -type Contract struct { - ContractCaller // Read-only binding to the contract - ContractTransactor // Write-only binding to the contract - ContractFilterer // Log filterer for contract events -} - -// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. -type ContractCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ContractTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ContractFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ContractSession struct { - Contract *Contract // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ContractCallerSession struct { - Contract *ContractCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ContractTransactorSession struct { - Contract *ContractTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. -type ContractRaw struct { - Contract *Contract // Generic contract binding to access the raw methods on -} - -// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ContractCallerRaw struct { - Contract *ContractCaller // Generic read-only contract binding to access the raw methods on -} - -// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ContractTransactorRaw struct { - Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewContract creates a new instance of Contract, bound to a specific deployed contract. -func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { - contract, err := bindContract(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. -func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { - contract, err := bindContract(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ContractCaller{contract: contract}, nil -} - -// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. -func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { - contract, err := bindContract(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ContractTransactor{contract: contract}, nil -} - -// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. -func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { - contract, err := bindContract(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ContractFilterer{contract: contract}, nil -} - -// bindContract binds a generic wrapper to an already deployed contract. -func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ContractABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.contract.Transact(opts, method, params...) -} - -// AdvanceEpochs is a paid mutator transaction binding the contract method 0x0aeeca00. -// -// Solidity: function advanceEpochs(uint256 num) returns() -func (_Contract *ContractTransactor) AdvanceEpochs(opts *bind.TransactOpts, num *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "advanceEpochs", num) -} - -// AdvanceEpochs is a paid mutator transaction binding the contract method 0x0aeeca00. -// -// Solidity: function advanceEpochs(uint256 num) returns() -func (_Contract *ContractSession) AdvanceEpochs(num *big.Int) (*types.Transaction, error) { - return _Contract.Contract.AdvanceEpochs(&_Contract.TransactOpts, num) -} - -// AdvanceEpochs is a paid mutator transaction binding the contract method 0x0aeeca00. -// -// Solidity: function advanceEpochs(uint256 num) returns() -func (_Contract *ContractTransactorSession) AdvanceEpochs(num *big.Int) (*types.Transaction, error) { - return _Contract.Contract.AdvanceEpochs(&_Contract.TransactOpts, num) -} - -// CopyCode is a paid mutator transaction binding the contract method 0xd6a0c7af. -// -// Solidity: function copyCode(address acc, address from) returns() -func (_Contract *ContractTransactor) CopyCode(opts *bind.TransactOpts, acc common.Address, from common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "copyCode", acc, from) -} - -// CopyCode is a paid mutator transaction binding the contract method 0xd6a0c7af. -// -// Solidity: function copyCode(address acc, address from) returns() -func (_Contract *ContractSession) CopyCode(acc common.Address, from common.Address) (*types.Transaction, error) { - return _Contract.Contract.CopyCode(&_Contract.TransactOpts, acc, from) -} - -// CopyCode is a paid mutator transaction binding the contract method 0xd6a0c7af. -// -// Solidity: function copyCode(address acc, address from) returns() -func (_Contract *ContractTransactorSession) CopyCode(acc common.Address, from common.Address) (*types.Transaction, error) { - return _Contract.Contract.CopyCode(&_Contract.TransactOpts, acc, from) -} - -// DeactivateValidator is a paid mutator transaction binding the contract method 0x1e702f83. -// -// Solidity: function deactivateValidator(uint256 validatorID, uint256 status) returns() -func (_Contract *ContractTransactor) DeactivateValidator(opts *bind.TransactOpts, validatorID *big.Int, status *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "deactivateValidator", validatorID, status) -} - -// DeactivateValidator is a paid mutator transaction binding the contract method 0x1e702f83. -// -// Solidity: function deactivateValidator(uint256 validatorID, uint256 status) returns() -func (_Contract *ContractSession) DeactivateValidator(validatorID *big.Int, status *big.Int) (*types.Transaction, error) { - return _Contract.Contract.DeactivateValidator(&_Contract.TransactOpts, validatorID, status) -} - -// DeactivateValidator is a paid mutator transaction binding the contract method 0x1e702f83. -// -// Solidity: function deactivateValidator(uint256 validatorID, uint256 status) returns() -func (_Contract *ContractTransactorSession) DeactivateValidator(validatorID *big.Int, status *big.Int) (*types.Transaction, error) { - return _Contract.Contract.DeactivateValidator(&_Contract.TransactOpts, validatorID, status) -} - -// IncNonce is a paid mutator transaction binding the contract method 0x79bead38. -// -// Solidity: function incNonce(address acc, uint256 diff) returns() -func (_Contract *ContractTransactor) IncNonce(opts *bind.TransactOpts, acc common.Address, diff *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "incNonce", acc, diff) -} - -// IncNonce is a paid mutator transaction binding the contract method 0x79bead38. -// -// Solidity: function incNonce(address acc, uint256 diff) returns() -func (_Contract *ContractSession) IncNonce(acc common.Address, diff *big.Int) (*types.Transaction, error) { - return _Contract.Contract.IncNonce(&_Contract.TransactOpts, acc, diff) -} - -// IncNonce is a paid mutator transaction binding the contract method 0x79bead38. -// -// Solidity: function incNonce(address acc, uint256 diff) returns() -func (_Contract *ContractTransactorSession) IncNonce(acc common.Address, diff *big.Int) (*types.Transaction, error) { - return _Contract.Contract.IncNonce(&_Contract.TransactOpts, acc, diff) -} - -// Initialize is a paid mutator transaction binding the contract method 0x485cc955. -// -// Solidity: function initialize(address _backend, address _evmWriterAddress) returns() -func (_Contract *ContractTransactor) Initialize(opts *bind.TransactOpts, _backend common.Address, _evmWriterAddress common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "initialize", _backend, _evmWriterAddress) -} - -// Initialize is a paid mutator transaction binding the contract method 0x485cc955. -// -// Solidity: function initialize(address _backend, address _evmWriterAddress) returns() -func (_Contract *ContractSession) Initialize(_backend common.Address, _evmWriterAddress common.Address) (*types.Transaction, error) { - return _Contract.Contract.Initialize(&_Contract.TransactOpts, _backend, _evmWriterAddress) -} - -// Initialize is a paid mutator transaction binding the contract method 0x485cc955. -// -// Solidity: function initialize(address _backend, address _evmWriterAddress) returns() -func (_Contract *ContractTransactorSession) Initialize(_backend common.Address, _evmWriterAddress common.Address) (*types.Transaction, error) { - return _Contract.Contract.Initialize(&_Contract.TransactOpts, _backend, _evmWriterAddress) -} - -// SealEpoch is a paid mutator transaction binding the contract method 0xebdf104c. -// -// Solidity: function sealEpoch(uint256[] offlineTimes, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee) returns() -func (_Contract *ContractTransactor) SealEpoch(opts *bind.TransactOpts, offlineTimes []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "sealEpoch", offlineTimes, offlineBlocks, uptimes, originatedTxsFee) -} - -// SealEpoch is a paid mutator transaction binding the contract method 0xebdf104c. -// -// Solidity: function sealEpoch(uint256[] offlineTimes, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee) returns() -func (_Contract *ContractSession) SealEpoch(offlineTimes []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpoch(&_Contract.TransactOpts, offlineTimes, offlineBlocks, uptimes, originatedTxsFee) -} - -// SealEpoch is a paid mutator transaction binding the contract method 0xebdf104c. -// -// Solidity: function sealEpoch(uint256[] offlineTimes, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee) returns() -func (_Contract *ContractTransactorSession) SealEpoch(offlineTimes []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpoch(&_Contract.TransactOpts, offlineTimes, offlineBlocks, uptimes, originatedTxsFee) -} - -// SealEpochV1 is a paid mutator transaction binding the contract method 0x7f52e13e. -// -// Solidity: function sealEpochV1(uint256[] offlineTimes, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee, uint256 usedGas) returns() -func (_Contract *ContractTransactor) SealEpochV1(opts *bind.TransactOpts, offlineTimes []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int, usedGas *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "sealEpochV1", offlineTimes, offlineBlocks, uptimes, originatedTxsFee, usedGas) -} - -// SealEpochV1 is a paid mutator transaction binding the contract method 0x7f52e13e. -// -// Solidity: function sealEpochV1(uint256[] offlineTimes, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee, uint256 usedGas) returns() -func (_Contract *ContractSession) SealEpochV1(offlineTimes []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int, usedGas *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpochV1(&_Contract.TransactOpts, offlineTimes, offlineBlocks, uptimes, originatedTxsFee, usedGas) -} - -// SealEpochV1 is a paid mutator transaction binding the contract method 0x7f52e13e. -// -// Solidity: function sealEpochV1(uint256[] offlineTimes, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee, uint256 usedGas) returns() -func (_Contract *ContractTransactorSession) SealEpochV1(offlineTimes []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int, usedGas *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpochV1(&_Contract.TransactOpts, offlineTimes, offlineBlocks, uptimes, originatedTxsFee, usedGas) -} - -// SealEpochValidators is a paid mutator transaction binding the contract method 0xe08d7e66. -// -// Solidity: function sealEpochValidators(uint256[] nextValidatorIDs) returns() -func (_Contract *ContractTransactor) SealEpochValidators(opts *bind.TransactOpts, nextValidatorIDs []*big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "sealEpochValidators", nextValidatorIDs) -} - -// SealEpochValidators is a paid mutator transaction binding the contract method 0xe08d7e66. -// -// Solidity: function sealEpochValidators(uint256[] nextValidatorIDs) returns() -func (_Contract *ContractSession) SealEpochValidators(nextValidatorIDs []*big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpochValidators(&_Contract.TransactOpts, nextValidatorIDs) -} - -// SealEpochValidators is a paid mutator transaction binding the contract method 0xe08d7e66. -// -// Solidity: function sealEpochValidators(uint256[] nextValidatorIDs) returns() -func (_Contract *ContractTransactorSession) SealEpochValidators(nextValidatorIDs []*big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpochValidators(&_Contract.TransactOpts, nextValidatorIDs) -} - -// SetBackend is a paid mutator transaction binding the contract method 0xda7fc24f. -// -// Solidity: function setBackend(address _backend) returns() -func (_Contract *ContractTransactor) SetBackend(opts *bind.TransactOpts, _backend common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "setBackend", _backend) -} - -// SetBackend is a paid mutator transaction binding the contract method 0xda7fc24f. -// -// Solidity: function setBackend(address _backend) returns() -func (_Contract *ContractSession) SetBackend(_backend common.Address) (*types.Transaction, error) { - return _Contract.Contract.SetBackend(&_Contract.TransactOpts, _backend) -} - -// SetBackend is a paid mutator transaction binding the contract method 0xda7fc24f. -// -// Solidity: function setBackend(address _backend) returns() -func (_Contract *ContractTransactorSession) SetBackend(_backend common.Address) (*types.Transaction, error) { - return _Contract.Contract.SetBackend(&_Contract.TransactOpts, _backend) -} - -// SetBalance is a paid mutator transaction binding the contract method 0xe30443bc. -// -// Solidity: function setBalance(address acc, uint256 value) returns() -func (_Contract *ContractTransactor) SetBalance(opts *bind.TransactOpts, acc common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "setBalance", acc, value) -} - -// SetBalance is a paid mutator transaction binding the contract method 0xe30443bc. -// -// Solidity: function setBalance(address acc, uint256 value) returns() -func (_Contract *ContractSession) SetBalance(acc common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetBalance(&_Contract.TransactOpts, acc, value) -} - -// SetBalance is a paid mutator transaction binding the contract method 0xe30443bc. -// -// Solidity: function setBalance(address acc, uint256 value) returns() -func (_Contract *ContractTransactorSession) SetBalance(acc common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetBalance(&_Contract.TransactOpts, acc, value) -} - -// SetGenesisDelegation is a paid mutator transaction binding the contract method 0x18f628d4. -// -// Solidity: function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake, uint256 lockedStake, uint256 lockupFromEpoch, uint256 lockupEndTime, uint256 lockupDuration, uint256 earlyUnlockPenalty, uint256 rewards) returns() -func (_Contract *ContractTransactor) SetGenesisDelegation(opts *bind.TransactOpts, delegator common.Address, toValidatorID *big.Int, stake *big.Int, lockedStake *big.Int, lockupFromEpoch *big.Int, lockupEndTime *big.Int, lockupDuration *big.Int, earlyUnlockPenalty *big.Int, rewards *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "setGenesisDelegation", delegator, toValidatorID, stake, lockedStake, lockupFromEpoch, lockupEndTime, lockupDuration, earlyUnlockPenalty, rewards) -} - -// SetGenesisDelegation is a paid mutator transaction binding the contract method 0x18f628d4. -// -// Solidity: function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake, uint256 lockedStake, uint256 lockupFromEpoch, uint256 lockupEndTime, uint256 lockupDuration, uint256 earlyUnlockPenalty, uint256 rewards) returns() -func (_Contract *ContractSession) SetGenesisDelegation(delegator common.Address, toValidatorID *big.Int, stake *big.Int, lockedStake *big.Int, lockupFromEpoch *big.Int, lockupEndTime *big.Int, lockupDuration *big.Int, earlyUnlockPenalty *big.Int, rewards *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisDelegation(&_Contract.TransactOpts, delegator, toValidatorID, stake, lockedStake, lockupFromEpoch, lockupEndTime, lockupDuration, earlyUnlockPenalty, rewards) -} - -// SetGenesisDelegation is a paid mutator transaction binding the contract method 0x18f628d4. -// -// Solidity: function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake, uint256 lockedStake, uint256 lockupFromEpoch, uint256 lockupEndTime, uint256 lockupDuration, uint256 earlyUnlockPenalty, uint256 rewards) returns() -func (_Contract *ContractTransactorSession) SetGenesisDelegation(delegator common.Address, toValidatorID *big.Int, stake *big.Int, lockedStake *big.Int, lockupFromEpoch *big.Int, lockupEndTime *big.Int, lockupDuration *big.Int, earlyUnlockPenalty *big.Int, rewards *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisDelegation(&_Contract.TransactOpts, delegator, toValidatorID, stake, lockedStake, lockupFromEpoch, lockupEndTime, lockupDuration, earlyUnlockPenalty, rewards) -} - -// SetGenesisValidator is a paid mutator transaction binding the contract method 0x4feb92f3. -// -// Solidity: function setGenesisValidator(address _auth, uint256 validatorID, bytes pubkey, uint256 status, uint256 createdEpoch, uint256 createdTime, uint256 deactivatedEpoch, uint256 deactivatedTime) returns() -func (_Contract *ContractTransactor) SetGenesisValidator(opts *bind.TransactOpts, _auth common.Address, validatorID *big.Int, pubkey []byte, status *big.Int, createdEpoch *big.Int, createdTime *big.Int, deactivatedEpoch *big.Int, deactivatedTime *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "setGenesisValidator", _auth, validatorID, pubkey, status, createdEpoch, createdTime, deactivatedEpoch, deactivatedTime) -} - -// SetGenesisValidator is a paid mutator transaction binding the contract method 0x4feb92f3. -// -// Solidity: function setGenesisValidator(address _auth, uint256 validatorID, bytes pubkey, uint256 status, uint256 createdEpoch, uint256 createdTime, uint256 deactivatedEpoch, uint256 deactivatedTime) returns() -func (_Contract *ContractSession) SetGenesisValidator(_auth common.Address, validatorID *big.Int, pubkey []byte, status *big.Int, createdEpoch *big.Int, createdTime *big.Int, deactivatedEpoch *big.Int, deactivatedTime *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisValidator(&_Contract.TransactOpts, _auth, validatorID, pubkey, status, createdEpoch, createdTime, deactivatedEpoch, deactivatedTime) -} - -// SetGenesisValidator is a paid mutator transaction binding the contract method 0x4feb92f3. -// -// Solidity: function setGenesisValidator(address _auth, uint256 validatorID, bytes pubkey, uint256 status, uint256 createdEpoch, uint256 createdTime, uint256 deactivatedEpoch, uint256 deactivatedTime) returns() -func (_Contract *ContractTransactorSession) SetGenesisValidator(_auth common.Address, validatorID *big.Int, pubkey []byte, status *big.Int, createdEpoch *big.Int, createdTime *big.Int, deactivatedEpoch *big.Int, deactivatedTime *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisValidator(&_Contract.TransactOpts, _auth, validatorID, pubkey, status, createdEpoch, createdTime, deactivatedEpoch, deactivatedTime) -} - -// SetStorage is a paid mutator transaction binding the contract method 0x39e503ab. -// -// Solidity: function setStorage(address acc, bytes32 key, bytes32 value) returns() -func (_Contract *ContractTransactor) SetStorage(opts *bind.TransactOpts, acc common.Address, key [32]byte, value [32]byte) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "setStorage", acc, key, value) -} - -// SetStorage is a paid mutator transaction binding the contract method 0x39e503ab. -// -// Solidity: function setStorage(address acc, bytes32 key, bytes32 value) returns() -func (_Contract *ContractSession) SetStorage(acc common.Address, key [32]byte, value [32]byte) (*types.Transaction, error) { - return _Contract.Contract.SetStorage(&_Contract.TransactOpts, acc, key, value) -} - -// SetStorage is a paid mutator transaction binding the contract method 0x39e503ab. -// -// Solidity: function setStorage(address acc, bytes32 key, bytes32 value) returns() -func (_Contract *ContractTransactorSession) SetStorage(acc common.Address, key [32]byte, value [32]byte) (*types.Transaction, error) { - return _Contract.Contract.SetStorage(&_Contract.TransactOpts, acc, key, value) -} - -// SwapCode is a paid mutator transaction binding the contract method 0x07690b2a. -// -// Solidity: function swapCode(address acc, address with) returns() -func (_Contract *ContractTransactor) SwapCode(opts *bind.TransactOpts, acc common.Address, with common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "swapCode", acc, with) -} - -// SwapCode is a paid mutator transaction binding the contract method 0x07690b2a. -// -// Solidity: function swapCode(address acc, address with) returns() -func (_Contract *ContractSession) SwapCode(acc common.Address, with common.Address) (*types.Transaction, error) { - return _Contract.Contract.SwapCode(&_Contract.TransactOpts, acc, with) -} - -// SwapCode is a paid mutator transaction binding the contract method 0x07690b2a. -// -// Solidity: function swapCode(address acc, address with) returns() -func (_Contract *ContractTransactorSession) SwapCode(acc common.Address, with common.Address) (*types.Transaction, error) { - return _Contract.Contract.SwapCode(&_Contract.TransactOpts, acc, with) -} - -// UpdateNetworkRules is a paid mutator transaction binding the contract method 0xb9cc6b1c. -// -// Solidity: function updateNetworkRules(bytes diff) returns() -func (_Contract *ContractTransactor) UpdateNetworkRules(opts *bind.TransactOpts, diff []byte) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateNetworkRules", diff) -} - -// UpdateNetworkRules is a paid mutator transaction binding the contract method 0xb9cc6b1c. -// -// Solidity: function updateNetworkRules(bytes diff) returns() -func (_Contract *ContractSession) UpdateNetworkRules(diff []byte) (*types.Transaction, error) { - return _Contract.Contract.UpdateNetworkRules(&_Contract.TransactOpts, diff) -} - -// UpdateNetworkRules is a paid mutator transaction binding the contract method 0xb9cc6b1c. -// -// Solidity: function updateNetworkRules(bytes diff) returns() -func (_Contract *ContractTransactorSession) UpdateNetworkRules(diff []byte) (*types.Transaction, error) { - return _Contract.Contract.UpdateNetworkRules(&_Contract.TransactOpts, diff) -} - -// UpdateNetworkVersion is a paid mutator transaction binding the contract method 0x267ab446. -// -// Solidity: function updateNetworkVersion(uint256 version) returns() -func (_Contract *ContractTransactor) UpdateNetworkVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateNetworkVersion", version) -} - -// UpdateNetworkVersion is a paid mutator transaction binding the contract method 0x267ab446. -// -// Solidity: function updateNetworkVersion(uint256 version) returns() -func (_Contract *ContractSession) UpdateNetworkVersion(version *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateNetworkVersion(&_Contract.TransactOpts, version) -} - -// UpdateNetworkVersion is a paid mutator transaction binding the contract method 0x267ab446. -// -// Solidity: function updateNetworkVersion(uint256 version) returns() -func (_Contract *ContractTransactorSession) UpdateNetworkVersion(version *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateNetworkVersion(&_Contract.TransactOpts, version) -} - -// UpdateValidatorPubkey is a paid mutator transaction binding the contract method 0x242a6e3f. -// -// Solidity: function updateValidatorPubkey(uint256 validatorID, bytes pubkey) returns() -func (_Contract *ContractTransactor) UpdateValidatorPubkey(opts *bind.TransactOpts, validatorID *big.Int, pubkey []byte) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateValidatorPubkey", validatorID, pubkey) -} - -// UpdateValidatorPubkey is a paid mutator transaction binding the contract method 0x242a6e3f. -// -// Solidity: function updateValidatorPubkey(uint256 validatorID, bytes pubkey) returns() -func (_Contract *ContractSession) UpdateValidatorPubkey(validatorID *big.Int, pubkey []byte) (*types.Transaction, error) { - return _Contract.Contract.UpdateValidatorPubkey(&_Contract.TransactOpts, validatorID, pubkey) -} - -// UpdateValidatorPubkey is a paid mutator transaction binding the contract method 0x242a6e3f. -// -// Solidity: function updateValidatorPubkey(uint256 validatorID, bytes pubkey) returns() -func (_Contract *ContractTransactorSession) UpdateValidatorPubkey(validatorID *big.Int, pubkey []byte) (*types.Transaction, error) { - return _Contract.Contract.UpdateValidatorPubkey(&_Contract.TransactOpts, validatorID, pubkey) -} - -// UpdateValidatorWeight is a paid mutator transaction binding the contract method 0xa4066fbe. -// -// Solidity: function updateValidatorWeight(uint256 validatorID, uint256 value) returns() -func (_Contract *ContractTransactor) UpdateValidatorWeight(opts *bind.TransactOpts, validatorID *big.Int, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateValidatorWeight", validatorID, value) -} - -// UpdateValidatorWeight is a paid mutator transaction binding the contract method 0xa4066fbe. -// -// Solidity: function updateValidatorWeight(uint256 validatorID, uint256 value) returns() -func (_Contract *ContractSession) UpdateValidatorWeight(validatorID *big.Int, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateValidatorWeight(&_Contract.TransactOpts, validatorID, value) -} - -// UpdateValidatorWeight is a paid mutator transaction binding the contract method 0xa4066fbe. -// -// Solidity: function updateValidatorWeight(uint256 validatorID, uint256 value) returns() -func (_Contract *ContractTransactorSession) UpdateValidatorWeight(validatorID *big.Int, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateValidatorWeight(&_Contract.TransactOpts, validatorID, value) -} - -// ContractAdvanceEpochsIterator is returned from FilterAdvanceEpochs and is used to iterate over the raw logs and unpacked data for AdvanceEpochs events raised by the Contract contract. -type ContractAdvanceEpochsIterator struct { - Event *ContractAdvanceEpochs // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractAdvanceEpochsIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractAdvanceEpochs) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractAdvanceEpochs) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractAdvanceEpochsIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractAdvanceEpochsIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractAdvanceEpochs represents a AdvanceEpochs event raised by the Contract contract. -type ContractAdvanceEpochs struct { - Num *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterAdvanceEpochs is a free log retrieval operation binding the contract event 0x0151256d62457b809bbc891b1f81c6dd0b9987552c70ce915b519750cd434dd1. -// -// Solidity: event AdvanceEpochs(uint256 num) -func (_Contract *ContractFilterer) FilterAdvanceEpochs(opts *bind.FilterOpts) (*ContractAdvanceEpochsIterator, error) { - - logs, sub, err := _Contract.contract.FilterLogs(opts, "AdvanceEpochs") - if err != nil { - return nil, err - } - return &ContractAdvanceEpochsIterator{contract: _Contract.contract, event: "AdvanceEpochs", logs: logs, sub: sub}, nil -} - -// WatchAdvanceEpochs is a free log subscription operation binding the contract event 0x0151256d62457b809bbc891b1f81c6dd0b9987552c70ce915b519750cd434dd1. -// -// Solidity: event AdvanceEpochs(uint256 num) -func (_Contract *ContractFilterer) WatchAdvanceEpochs(opts *bind.WatchOpts, sink chan<- *ContractAdvanceEpochs) (event.Subscription, error) { - - logs, sub, err := _Contract.contract.WatchLogs(opts, "AdvanceEpochs") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractAdvanceEpochs) - if err := _Contract.contract.UnpackLog(event, "AdvanceEpochs", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseAdvanceEpochs is a log parse operation binding the contract event 0x0151256d62457b809bbc891b1f81c6dd0b9987552c70ce915b519750cd434dd1. -// -// Solidity: event AdvanceEpochs(uint256 num) -func (_Contract *ContractFilterer) ParseAdvanceEpochs(log types.Log) (*ContractAdvanceEpochs, error) { - event := new(ContractAdvanceEpochs) - if err := _Contract.contract.UnpackLog(event, "AdvanceEpochs", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUpdateNetworkRulesIterator is returned from FilterUpdateNetworkRules and is used to iterate over the raw logs and unpacked data for UpdateNetworkRules events raised by the Contract contract. -type ContractUpdateNetworkRulesIterator struct { - Event *ContractUpdateNetworkRules // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUpdateNetworkRulesIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUpdateNetworkRules) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUpdateNetworkRules) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUpdateNetworkRulesIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUpdateNetworkRulesIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUpdateNetworkRules represents a UpdateNetworkRules event raised by the Contract contract. -type ContractUpdateNetworkRules struct { - Diff []byte - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdateNetworkRules is a free log retrieval operation binding the contract event 0x47d10eed096a44e3d0abc586c7e3a5d6cb5358cc90e7d437cd0627f7e765fb99. -// -// Solidity: event UpdateNetworkRules(bytes diff) -func (_Contract *ContractFilterer) FilterUpdateNetworkRules(opts *bind.FilterOpts) (*ContractUpdateNetworkRulesIterator, error) { - - logs, sub, err := _Contract.contract.FilterLogs(opts, "UpdateNetworkRules") - if err != nil { - return nil, err - } - return &ContractUpdateNetworkRulesIterator{contract: _Contract.contract, event: "UpdateNetworkRules", logs: logs, sub: sub}, nil -} - -// WatchUpdateNetworkRules is a free log subscription operation binding the contract event 0x47d10eed096a44e3d0abc586c7e3a5d6cb5358cc90e7d437cd0627f7e765fb99. -// -// Solidity: event UpdateNetworkRules(bytes diff) -func (_Contract *ContractFilterer) WatchUpdateNetworkRules(opts *bind.WatchOpts, sink chan<- *ContractUpdateNetworkRules) (event.Subscription, error) { - - logs, sub, err := _Contract.contract.WatchLogs(opts, "UpdateNetworkRules") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUpdateNetworkRules) - if err := _Contract.contract.UnpackLog(event, "UpdateNetworkRules", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdateNetworkRules is a log parse operation binding the contract event 0x47d10eed096a44e3d0abc586c7e3a5d6cb5358cc90e7d437cd0627f7e765fb99. -// -// Solidity: event UpdateNetworkRules(bytes diff) -func (_Contract *ContractFilterer) ParseUpdateNetworkRules(log types.Log) (*ContractUpdateNetworkRules, error) { - event := new(ContractUpdateNetworkRules) - if err := _Contract.contract.UnpackLog(event, "UpdateNetworkRules", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUpdateNetworkVersionIterator is returned from FilterUpdateNetworkVersion and is used to iterate over the raw logs and unpacked data for UpdateNetworkVersion events raised by the Contract contract. -type ContractUpdateNetworkVersionIterator struct { - Event *ContractUpdateNetworkVersion // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUpdateNetworkVersionIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUpdateNetworkVersion) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUpdateNetworkVersion) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUpdateNetworkVersionIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUpdateNetworkVersionIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUpdateNetworkVersion represents a UpdateNetworkVersion event raised by the Contract contract. -type ContractUpdateNetworkVersion struct { - Version *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdateNetworkVersion is a free log retrieval operation binding the contract event 0x2ccdfd47cf0c1f1069d949f1789bb79b2f12821f021634fc835af1de66ea2feb. -// -// Solidity: event UpdateNetworkVersion(uint256 version) -func (_Contract *ContractFilterer) FilterUpdateNetworkVersion(opts *bind.FilterOpts) (*ContractUpdateNetworkVersionIterator, error) { - - logs, sub, err := _Contract.contract.FilterLogs(opts, "UpdateNetworkVersion") - if err != nil { - return nil, err - } - return &ContractUpdateNetworkVersionIterator{contract: _Contract.contract, event: "UpdateNetworkVersion", logs: logs, sub: sub}, nil -} - -// WatchUpdateNetworkVersion is a free log subscription operation binding the contract event 0x2ccdfd47cf0c1f1069d949f1789bb79b2f12821f021634fc835af1de66ea2feb. -// -// Solidity: event UpdateNetworkVersion(uint256 version) -func (_Contract *ContractFilterer) WatchUpdateNetworkVersion(opts *bind.WatchOpts, sink chan<- *ContractUpdateNetworkVersion) (event.Subscription, error) { - - logs, sub, err := _Contract.contract.WatchLogs(opts, "UpdateNetworkVersion") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUpdateNetworkVersion) - if err := _Contract.contract.UnpackLog(event, "UpdateNetworkVersion", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdateNetworkVersion is a log parse operation binding the contract event 0x2ccdfd47cf0c1f1069d949f1789bb79b2f12821f021634fc835af1de66ea2feb. -// -// Solidity: event UpdateNetworkVersion(uint256 version) -func (_Contract *ContractFilterer) ParseUpdateNetworkVersion(log types.Log) (*ContractUpdateNetworkVersion, error) { - event := new(ContractUpdateNetworkVersion) - if err := _Contract.contract.UnpackLog(event, "UpdateNetworkVersion", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUpdateValidatorPubkeyIterator is returned from FilterUpdateValidatorPubkey and is used to iterate over the raw logs and unpacked data for UpdateValidatorPubkey events raised by the Contract contract. -type ContractUpdateValidatorPubkeyIterator struct { - Event *ContractUpdateValidatorPubkey // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUpdateValidatorPubkeyIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUpdateValidatorPubkey) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUpdateValidatorPubkey) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUpdateValidatorPubkeyIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUpdateValidatorPubkeyIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUpdateValidatorPubkey represents a UpdateValidatorPubkey event raised by the Contract contract. -type ContractUpdateValidatorPubkey struct { - ValidatorID *big.Int - Pubkey []byte - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdateValidatorPubkey is a free log retrieval operation binding the contract event 0x0f0ef1ab97439def0a9d2c6d9dc166207f1b13b99e62b442b2993d6153c63a6e. -// -// Solidity: event UpdateValidatorPubkey(uint256 indexed validatorID, bytes pubkey) -func (_Contract *ContractFilterer) FilterUpdateValidatorPubkey(opts *bind.FilterOpts, validatorID []*big.Int) (*ContractUpdateValidatorPubkeyIterator, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "UpdateValidatorPubkey", validatorIDRule) - if err != nil { - return nil, err - } - return &ContractUpdateValidatorPubkeyIterator{contract: _Contract.contract, event: "UpdateValidatorPubkey", logs: logs, sub: sub}, nil -} - -// WatchUpdateValidatorPubkey is a free log subscription operation binding the contract event 0x0f0ef1ab97439def0a9d2c6d9dc166207f1b13b99e62b442b2993d6153c63a6e. -// -// Solidity: event UpdateValidatorPubkey(uint256 indexed validatorID, bytes pubkey) -func (_Contract *ContractFilterer) WatchUpdateValidatorPubkey(opts *bind.WatchOpts, sink chan<- *ContractUpdateValidatorPubkey, validatorID []*big.Int) (event.Subscription, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "UpdateValidatorPubkey", validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUpdateValidatorPubkey) - if err := _Contract.contract.UnpackLog(event, "UpdateValidatorPubkey", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdateValidatorPubkey is a log parse operation binding the contract event 0x0f0ef1ab97439def0a9d2c6d9dc166207f1b13b99e62b442b2993d6153c63a6e. -// -// Solidity: event UpdateValidatorPubkey(uint256 indexed validatorID, bytes pubkey) -func (_Contract *ContractFilterer) ParseUpdateValidatorPubkey(log types.Log) (*ContractUpdateValidatorPubkey, error) { - event := new(ContractUpdateValidatorPubkey) - if err := _Contract.contract.UnpackLog(event, "UpdateValidatorPubkey", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUpdateValidatorWeightIterator is returned from FilterUpdateValidatorWeight and is used to iterate over the raw logs and unpacked data for UpdateValidatorWeight events raised by the Contract contract. -type ContractUpdateValidatorWeightIterator struct { - Event *ContractUpdateValidatorWeight // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUpdateValidatorWeightIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUpdateValidatorWeight) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUpdateValidatorWeight) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUpdateValidatorWeightIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUpdateValidatorWeightIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUpdateValidatorWeight represents a UpdateValidatorWeight event raised by the Contract contract. -type ContractUpdateValidatorWeight struct { - ValidatorID *big.Int - Weight *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdateValidatorWeight is a free log retrieval operation binding the contract event 0xb975807576e3b1461be7de07ebf7d20e4790ed802d7a0c4fdd0a1a13df72a935. -// -// Solidity: event UpdateValidatorWeight(uint256 indexed validatorID, uint256 weight) -func (_Contract *ContractFilterer) FilterUpdateValidatorWeight(opts *bind.FilterOpts, validatorID []*big.Int) (*ContractUpdateValidatorWeightIterator, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "UpdateValidatorWeight", validatorIDRule) - if err != nil { - return nil, err - } - return &ContractUpdateValidatorWeightIterator{contract: _Contract.contract, event: "UpdateValidatorWeight", logs: logs, sub: sub}, nil -} - -// WatchUpdateValidatorWeight is a free log subscription operation binding the contract event 0xb975807576e3b1461be7de07ebf7d20e4790ed802d7a0c4fdd0a1a13df72a935. -// -// Solidity: event UpdateValidatorWeight(uint256 indexed validatorID, uint256 weight) -func (_Contract *ContractFilterer) WatchUpdateValidatorWeight(opts *bind.WatchOpts, sink chan<- *ContractUpdateValidatorWeight, validatorID []*big.Int) (event.Subscription, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "UpdateValidatorWeight", validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUpdateValidatorWeight) - if err := _Contract.contract.UnpackLog(event, "UpdateValidatorWeight", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdateValidatorWeight is a log parse operation binding the contract event 0xb975807576e3b1461be7de07ebf7d20e4790ed802d7a0c4fdd0a1a13df72a935. -// -// Solidity: event UpdateValidatorWeight(uint256 indexed validatorID, uint256 weight) -func (_Contract *ContractFilterer) ParseUpdateValidatorWeight(log types.Log) (*ContractUpdateValidatorWeight, error) { - event := new(ContractUpdateValidatorWeight) - if err := _Contract.contract.UnpackLog(event, "UpdateValidatorWeight", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUpdatedBackendIterator is returned from FilterUpdatedBackend and is used to iterate over the raw logs and unpacked data for UpdatedBackend events raised by the Contract contract. -type ContractUpdatedBackendIterator struct { - Event *ContractUpdatedBackend // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUpdatedBackendIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUpdatedBackend) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUpdatedBackend) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUpdatedBackendIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUpdatedBackendIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUpdatedBackend represents a UpdatedBackend event raised by the Contract contract. -type ContractUpdatedBackend struct { - Backend common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdatedBackend is a free log retrieval operation binding the contract event 0x64ee8f7bfc37fc205d7194ee3d64947ab7b57e663cd0d1abd3ef245035830693. -// -// Solidity: event UpdatedBackend(address indexed backend) -func (_Contract *ContractFilterer) FilterUpdatedBackend(opts *bind.FilterOpts, backend []common.Address) (*ContractUpdatedBackendIterator, error) { - - var backendRule []interface{} - for _, backendItem := range backend { - backendRule = append(backendRule, backendItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "UpdatedBackend", backendRule) - if err != nil { - return nil, err - } - return &ContractUpdatedBackendIterator{contract: _Contract.contract, event: "UpdatedBackend", logs: logs, sub: sub}, nil -} - -// WatchUpdatedBackend is a free log subscription operation binding the contract event 0x64ee8f7bfc37fc205d7194ee3d64947ab7b57e663cd0d1abd3ef245035830693. -// -// Solidity: event UpdatedBackend(address indexed backend) -func (_Contract *ContractFilterer) WatchUpdatedBackend(opts *bind.WatchOpts, sink chan<- *ContractUpdatedBackend, backend []common.Address) (event.Subscription, error) { - - var backendRule []interface{} - for _, backendItem := range backend { - backendRule = append(backendRule, backendItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "UpdatedBackend", backendRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUpdatedBackend) - if err := _Contract.contract.UnpackLog(event, "UpdatedBackend", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdatedBackend is a log parse operation binding the contract event 0x64ee8f7bfc37fc205d7194ee3d64947ab7b57e663cd0d1abd3ef245035830693. -// -// Solidity: event UpdatedBackend(address indexed backend) -func (_Contract *ContractFilterer) ParseUpdatedBackend(log types.Log) (*ContractUpdatedBackend, error) { - event := new(ContractUpdatedBackend) - if err := _Contract.contract.UnpackLog(event, "UpdatedBackend", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -var ContractBinRuntime = "0x608060405234801561001057600080fd5b50600436106101365760003560e01c806379bead38116100b2578063d6a0c7af11610081578063e08d7e6611610066578063e08d7e6614610676578063e30443bc146106e6578063ebdf104c1461071f57610136565b8063d6a0c7af14610608578063da7fc24f1461064357610136565b806379bead38146103d65780637f52e13e1461040f578063a4066fbe14610575578063b9cc6b1c1461059857610136565b8063242a6e3f1161010957806339e503ab116100ee57806339e503ab146102b1578063485cc955146102f05780634feb92f31461032b57610136565b8063242a6e3f1461021d578063267ab4461461029457610136565b806307690b2a1461013b5780630aeeca001461017857806318f628d4146101955780631e702f83146101fa575b600080fd5b6101766004803603604081101561015157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610885565b005b6101766004803603602081101561018e57600080fd5b5035610989565b61017660048036036101208110156101ac57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e0810135906101000135610a2b565b6101766004803603604081101561021057600080fd5b5080359060200135610b4f565b6101766004803603604081101561023357600080fd5b8135919081019060408101602082013564010000000081111561025557600080fd5b82018360208201111561026757600080fd5b8035906020019184600183028401116401000000008311171561028957600080fd5b509092509050610c1c565b610176600480360360208110156102aa57600080fd5b5035610cee565b610176600480360360608110156102c757600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060208101359060400135610d90565b6101766004803603604081101561030657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610e9b565b610176600480360361010081101561034257600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b919350915080359060208101359060408101359060608101359060800135611043565b610176600480360360408110156103ec57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561119b565b610176600480360360a081101561042557600080fd5b81019060208101813564010000000081111561044057600080fd5b82018360208201111561045257600080fd5b8035906020019184602083028401116401000000008311171561047457600080fd5b91939092909160208101903564010000000081111561049257600080fd5b8201836020820111156104a457600080fd5b803590602001918460208302840111640100000000831117156104c657600080fd5b9193909290916020810190356401000000008111156104e457600080fd5b8201836020820111156104f657600080fd5b8035906020019184602083028401116401000000008311171561051857600080fd5b91939092909160208101903564010000000081111561053657600080fd5b82018360208201111561054857600080fd5b8035906020019184602083028401116401000000008311171561056a57600080fd5b919350915035611282565b6101766004803603604081101561058b57600080fd5b5080359060200135611411565b610176600480360360208110156105ae57600080fd5b8101906020810181356401000000008111156105c957600080fd5b8201836020820111156105db57600080fd5b803590602001918460018302840111640100000000831117156105fd57600080fd5b5090925090506114b7565b6101766004803603604081101561061e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516611587565b6101766004803603602081101561065957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661166f565b6101766004803603602081101561068c57600080fd5b8101906020810181356401000000008111156106a757600080fd5b8201836020820111156106b957600080fd5b803590602001918460208302840111640100000000831117156106db57600080fd5b509092509050611763565b610176600480360360408110156106fc57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611859565b6101766004803603608081101561073557600080fd5b81019060208101813564010000000081111561075057600080fd5b82018360208201111561076257600080fd5b8035906020019184602083028401116401000000008311171561078457600080fd5b9193909290916020810190356401000000008111156107a257600080fd5b8201836020820111156107b457600080fd5b803590602001918460208302840111640100000000831117156107d657600080fd5b9193909290916020810190356401000000008111156107f457600080fd5b82018360208201111561080657600080fd5b8035906020019184602083028401116401000000008311171561082857600080fd5b91939092909160208101903564010000000081111561084657600080fd5b82018360208201111561085857600080fd5b8035906020019184602083028401116401000000008311171561087a57600080fd5b509092509050611940565b60345473ffffffffffffffffffffffffffffffffffffffff1633146108f1576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517f07690b2a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528481166024830152915191909216916307690b2a91604480830192600092919082900301818387803b15801561096d57600080fd5b505af1158015610981573d6000803e3d6000fd5b505050505050565b60345473ffffffffffffffffffffffffffffffffffffffff1633146109f5576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b6040805182815290517f0151256d62457b809bbc891b1f81c6dd0b9987552c70ce915b519750cd434dd19181900360200190a150565b3315610a7e576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603454604080517f18f628d400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c9052604482018b9052606482018a90526084820189905260a4820188905260c4820187905260e482018690526101048201859052915191909216916318f628d49161012480830192600092919082900301818387803b158015610b2c57600080fd5b505af1158015610b40573d6000803e3d6000fd5b50505050505050505050505050565b3315610ba2576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603454604080517f1e702f830000000000000000000000000000000000000000000000000000000081526004810185905260248101849052905173ffffffffffffffffffffffffffffffffffffffff90921691631e702f839160448082019260009290919082900301818387803b15801561096d57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff163314610c88576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b827f0f0ef1ab97439def0a9d2c6d9dc166207f1b13b99e62b442b2993d6153c63a6e838360405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2505050565b60345473ffffffffffffffffffffffffffffffffffffffff163314610d5a576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b6040805182815290517f2ccdfd47cf0c1f1069d949f1789bb79b2f12821f021634fc835af1de66ea2feb9181900360200190a150565b60345473ffffffffffffffffffffffffffffffffffffffff163314610dfc576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517f39e503ab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301526024820186905260448201859052915191909216916339e503ab91606480830192600092919082900301818387803b158015610e7e57600080fd5b505af1158015610e92573d6000803e3d6000fd5b50505050505050565b600054610100900460ff1680610eb45750610eb4611af5565b80610ec2575060005460ff16155b610efd5760405162461bcd60e51b815260040180806020018281038252602e815260200180611afc602e913960400191505060405180910390fd5b600054610100900460ff16158015610f6357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85169081179091556040517f64ee8f7bfc37fc205d7194ee3d64947ab7b57e663cd0d1abd3ef24503583069390600090a2603580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561103e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b505050565b3315611096576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634feb92f38a8a8a8a8a8a8a8a8a6040518a63ffffffff1660e01b8152600401808a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001898152602001806020018781526020018681526020018581526020018481526020018381526020018281038252898982818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b158015610b2c57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff163314611207576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517f79bead3800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260248201859052915191909216916379bead3891604480830192600092919082900301818387803b15801561096d57600080fd5b33156112d5576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663592fe0c08a8a8a8a8a8a8a8a8a6040518a63ffffffff1660e01b8152600401808060200180602001806020018060200186815260200185810385528e8e82818152602001925060200280828437600083820152601f01601f191690910186810385528c8152602090810191508d908d0280828437600083820152601f01601f191690910186810384528a8152602090810191508b908b0280828437600083820152601f01601f19169091018681038352888152602090810191508990890280828437600081840152601f19601f8201169050808301925050509d5050505050505050505050505050600060405180830381600087803b158015610b2c57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff16331461147d576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b60408051828152905183917fb975807576e3b1461be7de07ebf7d20e4790ed802d7a0c4fdd0a1a13df72a935919081900360200190a25050565b60345473ffffffffffffffffffffffffffffffffffffffff163314611523576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b7f47d10eed096a44e3d0abc586c7e3a5d6cb5358cc90e7d437cd0627f7e765fb99828260405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a15050565b60345473ffffffffffffffffffffffffffffffffffffffff1633146115f3576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517fd6a0c7af00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015284811660248301529151919092169163d6a0c7af91604480830192600092919082900301818387803b15801561096d57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff1633146116db576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b60405173ffffffffffffffffffffffffffffffffffffffff8216907f64ee8f7bfc37fc205d7194ee3d64947ab7b57e663cd0d1abd3ef24503583069390600090a2603480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b33156117b6576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b6034546040517fe08d7e660000000000000000000000000000000000000000000000000000000081526020600482018181526024830185905273ffffffffffffffffffffffffffffffffffffffff9093169263e08d7e6692869286929182916044909101908590850280828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b15801561096d57600080fd5b60345473ffffffffffffffffffffffffffffffffffffffff1633146118c5576040805162461bcd60e51b815260206004820152601960248201527f63616c6c6572206973206e6f7420746865206261636b656e6400000000000000604482015290519081900360640190fd5b603554604080517fe30443bc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590529151919092169163e30443bc91604480830192600092919082900301818387803b15801561096d57600080fd5b3315611993576040805162461bcd60e51b815260206004820152600c60248201527f6e6f742063616c6c61626c650000000000000000000000000000000000000000604482015290519081900360640190fd5b603460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663592fe0c0898989898989898963322adc3a6040518a63ffffffff1660e01b8152600401808060200180602001806020018060200186815260200185810385528e8e82818152602001925060200280828437600083820152601f01601f191690910186810385528c8152602090810191508d908d0280828437600083820152601f01601f191690910186810384528a8152602090810191508b908b0280828437600083820152601f01601f19169091018681038352888152602090810191508990890280828437600081840152601f19601f8201169050808301925050509d5050505050505050505050505050600060405180830381600087803b158015611ad357600080fd5b505af1158015611ae7573d6000803e3d6000fd5b505050505050505050505050565b303b159056fe436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a265627a7a72315820f5cb1667fae9152cab345389c6f9b54dccee170ca51c179d91361997f298acf464736f6c63430005110032" diff --git a/evm/go-x1/gossip/contract/driverauth100/contract.go b/evm/go-x1/gossip/contract/driverauth100/contract.go deleted file mode 100644 index 95a8dba..0000000 --- a/evm/go-x1/gossip/contract/driverauth100/contract.go +++ /dev/null @@ -1,860 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package driverauth100 - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// ContractMetaData contains all meta data concerning the Contract contract. -var ContractMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_sfc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_driver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newDriverAuth\",\"type\":\"address\"}],\"name\":\"migrateTo\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"executable\",\"type\":\"address\"}],\"name\":\"execute\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"executable\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"selfCodeHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"driverCodeHash\",\"type\":\"bytes32\"}],\"name\":\"mutExecute\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"diff\",\"type\":\"uint256\"}],\"name\":\"incBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"upgradeCode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"copyCode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"diff\",\"type\":\"uint256\"}],\"name\":\"incNonce\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"diff\",\"type\":\"bytes\"}],\"name\":\"updateNetworkRules\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minGasPrice\",\"type\":\"uint256\"}],\"name\":\"updateMinGasPrice\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateNetworkVersion\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"num\",\"type\":\"uint256\"}],\"name\":\"advanceEpochs\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"updateValidatorWeight\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"}],\"name\":\"updateValidatorPubkey\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_auth\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedTime\",\"type\":\"uint256\"}],\"name\":\"setGenesisValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockedStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupFromEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupEndTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyUnlockPenalty\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"}],\"name\":\"setGenesisDelegation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"}],\"name\":\"deactivateValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nextValidatorIDs\",\"type\":\"uint256[]\"}],\"name\":\"sealEpochValidators\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"offlineTimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"offlineBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"uptimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"originatedTxsFee\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"usedGas\",\"type\":\"uint256\"}],\"name\":\"sealEpoch\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50612269806100206000396000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806366e7ea0f116100e3578063b9cc6b1c1161008c578063e08d7e6611610066578063e08d7e6614610702578063f2fde38b14610772578063fd1b6ec1146107985761018d565b8063b9cc6b1c1461062c578063c0c53b8b1461069c578063d6a0c7af146106d45761018d565b80638da5cb5b116100bd5780638da5cb5b146105c95780638f32d59b146105ed578063a4066fbe146106095761018d565b806366e7ea0f14610569578063715018a61461059557806379bead381461059d5761018d565b8063242a6e3f116101455780634ddaf8f21161011f5780634ddaf8f21461033f5780634feb92f314610365578063592fe0c0146104035761018d565b8063242a6e3f14610285578063267ab446146102fc5780634b64e492146103195761018d565b806318f628d41161017657806318f628d4146101ce5780631cef4fab146102265780631e702f83146102625761018d565b806307aaf344146101925780630aeeca00146101b1575b600080fd5b6101af600480360360208110156101a857600080fd5b50356107c6565b005b6101af600480360360208110156101c757600080fd5b5035610969565b6101af60048036036101208110156101e557600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e0810135906101000135610a28565b6101af6004803603608081101561023c57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610b35565b6101af6004803603604081101561027857600080fd5b5080359060200135610ba0565b6101af6004803603604081101561029b57600080fd5b813591908101906040810160208201356401000000008111156102bd57600080fd5b8201836020820111156102cf57600080fd5b803590602001918460018302840111640100000000831117156102f157600080fd5b509092509050610c72565b6101af6004803603602081101561031257600080fd5b5035610d87565b6101af6004803603602081101561032f57600080fd5b50356001600160a01b0316610e46565b6101af6004803603602081101561035557600080fd5b50356001600160a01b0316610ed1565b6101af600480360361010081101561037c57600080fd5b6001600160a01b03823516916020810135918101906060810160408201356401000000008111156103ac57600080fd5b8201836020820111156103be57600080fd5b803590602001918460018302840111640100000000831117156103e057600080fd5b919350915080359060208101359060408101359060608101359060800135610f91565b6101af600480360360a081101561041957600080fd5b81019060208101813564010000000081111561043457600080fd5b82018360208201111561044657600080fd5b8035906020019184602083028401116401000000008311171561046857600080fd5b91939092909160208101903564010000000081111561048657600080fd5b82018360208201111561049857600080fd5b803590602001918460208302840111640100000000831117156104ba57600080fd5b9193909290916020810190356401000000008111156104d857600080fd5b8201836020820111156104ea57600080fd5b8035906020019184602083028401116401000000008311171561050c57600080fd5b91939092909160208101903564010000000081111561052a57600080fd5b82018360208201111561053c57600080fd5b8035906020019184602083028401116401000000008311171561055e57600080fd5b9193509150356110ab565b6101af6004803603604081101561057f57600080fd5b506001600160a01b038135169060200135611270565b6101af611394565b6101af600480360360408110156105b357600080fd5b506001600160a01b03813516906020013561144f565b6105d1611516565b604080516001600160a01b039092168252519081900360200190f35b6105f5611525565b604080519115158252519081900360200190f35b6101af6004803603604081101561061f57600080fd5b5080359060200135611536565b6101af6004803603602081101561064257600080fd5b81019060208101813564010000000081111561065d57600080fd5b82018360208201111561066f57600080fd5b8035906020019184600183028401116401000000008311171561069157600080fd5b509092509050611602565b6101af600480360360608110156106b257600080fd5b506001600160a01b0381358116916020810135821691604090910135166116eb565b6101af600480360360408110156106ea57600080fd5b506001600160a01b0381358116916020013516611838565b6101af6004803603602081101561071857600080fd5b81019060208101813564010000000081111561073357600080fd5b82018360208201111561074557600080fd5b8035906020019184602083028401116401000000008311171561076757600080fd5b509092509050611900565b6101af6004803603602081101561078857600080fd5b50356001600160a01b03166119df565b6101af600480360360408110156107ae57600080fd5b506001600160a01b0381358116916020013516611a41565b6066546001600160a01b03163314610825576040805162461bcd60e51b815260206004820152601e60248201527f63616c6c6572206973206e6f74207468652053464320636f6e74726163740000604482015290519081900360640190fd5b60675460408051808201909152601a81527f7b2245636f6e6f6d79223a7b224d696e4761735072696365223a00000000000060208201526001600160a01b039091169063b9cc6b1c906108b69061087b85611b04565b6040518060400160405280600281526020017f7d7d000000000000000000000000000000000000000000000000000000000000815250611c28565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109025781810151838201526020016108ea565b50505050905090810190601f16801561092f5780820380516001836020036101000a031916815260200191505b5092505050600060405180830381600087803b15801561094e57600080fd5b505af1158015610962573d6000803e3d6000fd5b5050505050565b610971611525565b6109c2576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517f0aeeca000000000000000000000000000000000000000000000000000000000081526004810184905290516001600160a01b0390921691630aeeca009160248082019260009290919082900301818387803b15801561094e57600080fd5b6067546001600160a01b03163314610a715760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b606654604080517f18f628d40000000000000000000000000000000000000000000000000000000081526001600160a01b038c81166004830152602482018c9052604482018b9052606482018a90526084820189905260a4820188905260c4820187905260e482018690526101048201859052915191909216916318f628d49161012480830192600092919082900301818387803b158015610b1257600080fd5b505af1158015610b26573d6000803e3d6000fd5b50505050505050505050505050565b610b3d611525565b610b8e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610b9a84848484611dc6565b50505050565b6067546001600160a01b03163314610be95760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b606654604080517f1e702f83000000000000000000000000000000000000000000000000000000008152600481018590526024810184905290516001600160a01b0390921691631e702f839160448082019260009290919082900301818387803b158015610c5657600080fd5b505af1158015610c6a573d6000803e3d6000fd5b505050505050565b6066546001600160a01b03163314610cd1576040805162461bcd60e51b815260206004820152601e60248201527f63616c6c6572206973206e6f74207468652053464320636f6e74726163740000604482015290519081900360640190fd5b606754604080517f242a6e3f0000000000000000000000000000000000000000000000000000000081526004810186815260248201928352604482018590526001600160a01b039093169263242a6e3f928792879287929091606401848480828437600081840152601f19601f820116905080830192505050945050505050600060405180830381600087803b158015610d6a57600080fd5b505af1158015610d7e573d6000803e3d6000fd5b50505050505050565b610d8f611525565b610de0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517f267ab4460000000000000000000000000000000000000000000000000000000081526004810184905290516001600160a01b039092169163267ab4469160248082019260009290919082900301818387803b15801561094e57600080fd5b610e4e611525565b610e9f576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610ece81610eab611516565b610eb430611ef0565b606754610ec9906001600160a01b0316611ef0565b611dc6565b50565b610ed9611525565b610f2a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517fda7fc24f0000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301529151919092169163da7fc24f91602480830192600092919082900301818387803b15801561094e57600080fd5b6067546001600160a01b03163314610fda5760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b606660009054906101000a90046001600160a01b03166001600160a01b0316634feb92f38a8a8a8a8a8a8a8a8a6040518a63ffffffff1660e01b8152600401808a6001600160a01b03166001600160a01b03168152602001898152602001806020018781526020018681526020018581526020018481526020018381526020018281038252898982818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b158015610b1257600080fd5b6067546001600160a01b031633146110f45760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b606660009054906101000a90046001600160a01b03166001600160a01b031663592fe0c08a8a8a8a8a8a8a8a8a6040518a63ffffffff1660e01b8152600401808060200180602001806020018060200186815260200185810385528e8e82818152602001925060200280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910186810385528c8152602090810191508d908d0280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910186810384528a8152602090810191508b908b0280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169091018681038352888152602090810191508990890280828437600081840152601f19601f8201169050808301925050509d5050505050505050505050505050600060405180830381600087803b158015610b1257600080fd5b6066546001600160a01b031633146112cf576040805162461bcd60e51b815260206004820152601e60248201527f63616c6c6572206973206e6f74207468652053464320636f6e74726163740000604482015290519081900360640190fd5b6066546001600160a01b0383811691161461131b5760405162461bcd60e51b81526004018080602001828103825260218152602001806121ef6021913960400191505060405180910390fd5b6067546001600160a01b039081169063e30443bc908490611345908216318563ffffffff611ef416565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610c5657600080fd5b61139c611525565b6113ed576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b611457611525565b6114a8576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517f79bead380000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052915191909216916379bead3891604480830192600092919082900301818387803b158015610c5657600080fd5b6033546001600160a01b031690565b6033546001600160a01b0316331490565b6066546001600160a01b03163314611595576040805162461bcd60e51b815260206004820152601e60248201527f63616c6c6572206973206e6f74207468652053464320636f6e74726163740000604482015290519081900360640190fd5b606754604080517fa4066fbe000000000000000000000000000000000000000000000000000000008152600481018590526024810184905290516001600160a01b039092169163a4066fbe9160448082019260009290919082900301818387803b158015610c5657600080fd5b61160a611525565b61165b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6067546040517fb9cc6b1c000000000000000000000000000000000000000000000000000000008152602060048201908152602482018490526001600160a01b039092169163b9cc6b1c91859185918190604401848480828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015610c5657600080fd5b600054610100900460ff16806117045750611704611f55565b80611712575060005460ff16155b61174d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806121c1602e913960400191505060405180910390fd5b600054610100900460ff161580156117b357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b6117bc82611f5b565b606780546001600160a01b038086167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560668054928716929091169190911790558015610b9a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550505050565b611840611525565b611891576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517fd6a0c7af0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015284811660248301529151919092169163d6a0c7af91604480830192600092919082900301818387803b158015610c5657600080fd5b6067546001600160a01b031633146119495760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b6066546040517fe08d7e66000000000000000000000000000000000000000000000000000000008152602060048201818152602483018590526001600160a01b039093169263e08d7e6692869286929182916044909101908590850280828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015610c5657600080fd5b6119e7611525565b611a38576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610ece816120bd565b611a49611525565b611a9a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b611aa382612176565b8015611ab35750611ab381612176565b611891576040805162461bcd60e51b815260206004820152600e60248201527f6e6f74206120636f6e7472616374000000000000000000000000000000000000604482015290519081900360640190fd5b606081611b45575060408051808201909152600181527f30000000000000000000000000000000000000000000000000000000000000006020820152611c23565b6000611b508361217c565b90506060816040519080825280601f01601f191660200182016040528015611b7f576020820181803883390190505b5090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015b8415611c1e57600a850660300160f81b828281518110611bc257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a850494507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611ba6565b509150505b919050565b60608084905060608490506060849050606081518351855101016040519080825280601f01601f191660200182016040528015611c6c576020820181803883390190505b509050806000805b8651811015611cdd57868181518110611c8957fe5b602001015160f81c60f81b838380600101945081518110611ca657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c74565b5060005b8551811015611d4a57858181518110611cf657fe5b602001015160f81c60f81b838380600101945081518110611d1357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611ce1565b5060005b8451811015611db757848181518110611d6357fe5b602001015160f81c60f81b838380600101945081518110611d8057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611d4e565b50909998505050505050505050565b611dcf846120bd565b836001600160a01b031663614619546040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e0a57600080fd5b505af1158015611e1e573d6000803e3d6000fd5b50505050611e2b836120bd565b81611e3530611ef0565b14611e87576040805162461bcd60e51b815260206004820152601c60248201527f73656c6620636f6465206861736820646f65736e2774206d6174636800000000604482015290519081900360640190fd5b6067548190611e9e906001600160a01b0316611ef0565b14610b9a576040805162461bcd60e51b815260206004820152601e60248201527f64726976657220636f6465206861736820646f65736e2774206d617463680000604482015290519081900360640190fd5b3f90565b600082820183811015611f4e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b303b1590565b600054610100900460ff1680611f745750611f74611f55565b80611f82575060005460ff16155b611fbd5760405162461bcd60e51b815260040180806020018281038252602e8152602001806121c1602e913960400191505060405180910390fd5b600054610100900460ff1615801561202357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156120b957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b6001600160a01b0381166121025760405162461bcd60e51b815260040180806020018281038252602681526020018061219b6026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b3b151590565b6000805b821561219457600101600a83049250612180565b9291505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564726563697069656e74206973206e6f74207468652053464320636f6e747261637463616c6c6572206973206e6f7420746865204e6f646544726976657220636f6e7472616374a265627a7a72315820e32e2bd9d4306bc53a2f1341ed34b7c36a48a87713cbfbf664b6cde5edf9f98e64736f6c63430005110032", -} - -// ContractABI is the input ABI used to generate the binding from. -// Deprecated: Use ContractMetaData.ABI instead. -var ContractABI = ContractMetaData.ABI - -// ContractBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ContractMetaData.Bin instead. -var ContractBin = ContractMetaData.Bin - -// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. -func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Contract, error) { - parsed, err := ContractMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// Contract is an auto generated Go binding around an Ethereum contract. -type Contract struct { - ContractCaller // Read-only binding to the contract - ContractTransactor // Write-only binding to the contract - ContractFilterer // Log filterer for contract events -} - -// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. -type ContractCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ContractTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ContractFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ContractSession struct { - Contract *Contract // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ContractCallerSession struct { - Contract *ContractCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ContractTransactorSession struct { - Contract *ContractTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. -type ContractRaw struct { - Contract *Contract // Generic contract binding to access the raw methods on -} - -// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ContractCallerRaw struct { - Contract *ContractCaller // Generic read-only contract binding to access the raw methods on -} - -// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ContractTransactorRaw struct { - Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewContract creates a new instance of Contract, bound to a specific deployed contract. -func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { - contract, err := bindContract(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. -func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { - contract, err := bindContract(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ContractCaller{contract: contract}, nil -} - -// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. -func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { - contract, err := bindContract(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ContractTransactor{contract: contract}, nil -} - -// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. -func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { - contract, err := bindContract(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ContractFilterer{contract: contract}, nil -} - -// bindContract binds a generic wrapper to an already deployed contract. -func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ContractABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.contract.Transact(opts, method, params...) -} - -// IsOwner is a free data retrieval call binding the contract method 0x8f32d59b. -// -// Solidity: function isOwner() view returns(bool) -func (_Contract *ContractCaller) IsOwner(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "isOwner") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// IsOwner is a free data retrieval call binding the contract method 0x8f32d59b. -// -// Solidity: function isOwner() view returns(bool) -func (_Contract *ContractSession) IsOwner() (bool, error) { - return _Contract.Contract.IsOwner(&_Contract.CallOpts) -} - -// IsOwner is a free data retrieval call binding the contract method 0x8f32d59b. -// -// Solidity: function isOwner() view returns(bool) -func (_Contract *ContractCallerSession) IsOwner() (bool, error) { - return _Contract.Contract.IsOwner(&_Contract.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Contract *ContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Contract *ContractSession) Owner() (common.Address, error) { - return _Contract.Contract.Owner(&_Contract.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Contract *ContractCallerSession) Owner() (common.Address, error) { - return _Contract.Contract.Owner(&_Contract.CallOpts) -} - -// AdvanceEpochs is a paid mutator transaction binding the contract method 0x0aeeca00. -// -// Solidity: function advanceEpochs(uint256 num) returns() -func (_Contract *ContractTransactor) AdvanceEpochs(opts *bind.TransactOpts, num *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "advanceEpochs", num) -} - -// AdvanceEpochs is a paid mutator transaction binding the contract method 0x0aeeca00. -// -// Solidity: function advanceEpochs(uint256 num) returns() -func (_Contract *ContractSession) AdvanceEpochs(num *big.Int) (*types.Transaction, error) { - return _Contract.Contract.AdvanceEpochs(&_Contract.TransactOpts, num) -} - -// AdvanceEpochs is a paid mutator transaction binding the contract method 0x0aeeca00. -// -// Solidity: function advanceEpochs(uint256 num) returns() -func (_Contract *ContractTransactorSession) AdvanceEpochs(num *big.Int) (*types.Transaction, error) { - return _Contract.Contract.AdvanceEpochs(&_Contract.TransactOpts, num) -} - -// CopyCode is a paid mutator transaction binding the contract method 0xd6a0c7af. -// -// Solidity: function copyCode(address acc, address from) returns() -func (_Contract *ContractTransactor) CopyCode(opts *bind.TransactOpts, acc common.Address, from common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "copyCode", acc, from) -} - -// CopyCode is a paid mutator transaction binding the contract method 0xd6a0c7af. -// -// Solidity: function copyCode(address acc, address from) returns() -func (_Contract *ContractSession) CopyCode(acc common.Address, from common.Address) (*types.Transaction, error) { - return _Contract.Contract.CopyCode(&_Contract.TransactOpts, acc, from) -} - -// CopyCode is a paid mutator transaction binding the contract method 0xd6a0c7af. -// -// Solidity: function copyCode(address acc, address from) returns() -func (_Contract *ContractTransactorSession) CopyCode(acc common.Address, from common.Address) (*types.Transaction, error) { - return _Contract.Contract.CopyCode(&_Contract.TransactOpts, acc, from) -} - -// DeactivateValidator is a paid mutator transaction binding the contract method 0x1e702f83. -// -// Solidity: function deactivateValidator(uint256 validatorID, uint256 status) returns() -func (_Contract *ContractTransactor) DeactivateValidator(opts *bind.TransactOpts, validatorID *big.Int, status *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "deactivateValidator", validatorID, status) -} - -// DeactivateValidator is a paid mutator transaction binding the contract method 0x1e702f83. -// -// Solidity: function deactivateValidator(uint256 validatorID, uint256 status) returns() -func (_Contract *ContractSession) DeactivateValidator(validatorID *big.Int, status *big.Int) (*types.Transaction, error) { - return _Contract.Contract.DeactivateValidator(&_Contract.TransactOpts, validatorID, status) -} - -// DeactivateValidator is a paid mutator transaction binding the contract method 0x1e702f83. -// -// Solidity: function deactivateValidator(uint256 validatorID, uint256 status) returns() -func (_Contract *ContractTransactorSession) DeactivateValidator(validatorID *big.Int, status *big.Int) (*types.Transaction, error) { - return _Contract.Contract.DeactivateValidator(&_Contract.TransactOpts, validatorID, status) -} - -// Execute is a paid mutator transaction binding the contract method 0x4b64e492. -// -// Solidity: function execute(address executable) returns() -func (_Contract *ContractTransactor) Execute(opts *bind.TransactOpts, executable common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "execute", executable) -} - -// Execute is a paid mutator transaction binding the contract method 0x4b64e492. -// -// Solidity: function execute(address executable) returns() -func (_Contract *ContractSession) Execute(executable common.Address) (*types.Transaction, error) { - return _Contract.Contract.Execute(&_Contract.TransactOpts, executable) -} - -// Execute is a paid mutator transaction binding the contract method 0x4b64e492. -// -// Solidity: function execute(address executable) returns() -func (_Contract *ContractTransactorSession) Execute(executable common.Address) (*types.Transaction, error) { - return _Contract.Contract.Execute(&_Contract.TransactOpts, executable) -} - -// IncBalance is a paid mutator transaction binding the contract method 0x66e7ea0f. -// -// Solidity: function incBalance(address acc, uint256 diff) returns() -func (_Contract *ContractTransactor) IncBalance(opts *bind.TransactOpts, acc common.Address, diff *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "incBalance", acc, diff) -} - -// IncBalance is a paid mutator transaction binding the contract method 0x66e7ea0f. -// -// Solidity: function incBalance(address acc, uint256 diff) returns() -func (_Contract *ContractSession) IncBalance(acc common.Address, diff *big.Int) (*types.Transaction, error) { - return _Contract.Contract.IncBalance(&_Contract.TransactOpts, acc, diff) -} - -// IncBalance is a paid mutator transaction binding the contract method 0x66e7ea0f. -// -// Solidity: function incBalance(address acc, uint256 diff) returns() -func (_Contract *ContractTransactorSession) IncBalance(acc common.Address, diff *big.Int) (*types.Transaction, error) { - return _Contract.Contract.IncBalance(&_Contract.TransactOpts, acc, diff) -} - -// IncNonce is a paid mutator transaction binding the contract method 0x79bead38. -// -// Solidity: function incNonce(address acc, uint256 diff) returns() -func (_Contract *ContractTransactor) IncNonce(opts *bind.TransactOpts, acc common.Address, diff *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "incNonce", acc, diff) -} - -// IncNonce is a paid mutator transaction binding the contract method 0x79bead38. -// -// Solidity: function incNonce(address acc, uint256 diff) returns() -func (_Contract *ContractSession) IncNonce(acc common.Address, diff *big.Int) (*types.Transaction, error) { - return _Contract.Contract.IncNonce(&_Contract.TransactOpts, acc, diff) -} - -// IncNonce is a paid mutator transaction binding the contract method 0x79bead38. -// -// Solidity: function incNonce(address acc, uint256 diff) returns() -func (_Contract *ContractTransactorSession) IncNonce(acc common.Address, diff *big.Int) (*types.Transaction, error) { - return _Contract.Contract.IncNonce(&_Contract.TransactOpts, acc, diff) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc0c53b8b. -// -// Solidity: function initialize(address _sfc, address _driver, address _owner) returns() -func (_Contract *ContractTransactor) Initialize(opts *bind.TransactOpts, _sfc common.Address, _driver common.Address, _owner common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "initialize", _sfc, _driver, _owner) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc0c53b8b. -// -// Solidity: function initialize(address _sfc, address _driver, address _owner) returns() -func (_Contract *ContractSession) Initialize(_sfc common.Address, _driver common.Address, _owner common.Address) (*types.Transaction, error) { - return _Contract.Contract.Initialize(&_Contract.TransactOpts, _sfc, _driver, _owner) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc0c53b8b. -// -// Solidity: function initialize(address _sfc, address _driver, address _owner) returns() -func (_Contract *ContractTransactorSession) Initialize(_sfc common.Address, _driver common.Address, _owner common.Address) (*types.Transaction, error) { - return _Contract.Contract.Initialize(&_Contract.TransactOpts, _sfc, _driver, _owner) -} - -// MigrateTo is a paid mutator transaction binding the contract method 0x4ddaf8f2. -// -// Solidity: function migrateTo(address newDriverAuth) returns() -func (_Contract *ContractTransactor) MigrateTo(opts *bind.TransactOpts, newDriverAuth common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "migrateTo", newDriverAuth) -} - -// MigrateTo is a paid mutator transaction binding the contract method 0x4ddaf8f2. -// -// Solidity: function migrateTo(address newDriverAuth) returns() -func (_Contract *ContractSession) MigrateTo(newDriverAuth common.Address) (*types.Transaction, error) { - return _Contract.Contract.MigrateTo(&_Contract.TransactOpts, newDriverAuth) -} - -// MigrateTo is a paid mutator transaction binding the contract method 0x4ddaf8f2. -// -// Solidity: function migrateTo(address newDriverAuth) returns() -func (_Contract *ContractTransactorSession) MigrateTo(newDriverAuth common.Address) (*types.Transaction, error) { - return _Contract.Contract.MigrateTo(&_Contract.TransactOpts, newDriverAuth) -} - -// MutExecute is a paid mutator transaction binding the contract method 0x1cef4fab. -// -// Solidity: function mutExecute(address executable, address newOwner, bytes32 selfCodeHash, bytes32 driverCodeHash) returns() -func (_Contract *ContractTransactor) MutExecute(opts *bind.TransactOpts, executable common.Address, newOwner common.Address, selfCodeHash [32]byte, driverCodeHash [32]byte) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "mutExecute", executable, newOwner, selfCodeHash, driverCodeHash) -} - -// MutExecute is a paid mutator transaction binding the contract method 0x1cef4fab. -// -// Solidity: function mutExecute(address executable, address newOwner, bytes32 selfCodeHash, bytes32 driverCodeHash) returns() -func (_Contract *ContractSession) MutExecute(executable common.Address, newOwner common.Address, selfCodeHash [32]byte, driverCodeHash [32]byte) (*types.Transaction, error) { - return _Contract.Contract.MutExecute(&_Contract.TransactOpts, executable, newOwner, selfCodeHash, driverCodeHash) -} - -// MutExecute is a paid mutator transaction binding the contract method 0x1cef4fab. -// -// Solidity: function mutExecute(address executable, address newOwner, bytes32 selfCodeHash, bytes32 driverCodeHash) returns() -func (_Contract *ContractTransactorSession) MutExecute(executable common.Address, newOwner common.Address, selfCodeHash [32]byte, driverCodeHash [32]byte) (*types.Transaction, error) { - return _Contract.Contract.MutExecute(&_Contract.TransactOpts, executable, newOwner, selfCodeHash, driverCodeHash) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Contract *ContractTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Contract *ContractSession) RenounceOwnership() (*types.Transaction, error) { - return _Contract.Contract.RenounceOwnership(&_Contract.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Contract *ContractTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _Contract.Contract.RenounceOwnership(&_Contract.TransactOpts) -} - -// SealEpoch is a paid mutator transaction binding the contract method 0x592fe0c0. -// -// Solidity: function sealEpoch(uint256[] offlineTimes, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee, uint256 usedGas) returns() -func (_Contract *ContractTransactor) SealEpoch(opts *bind.TransactOpts, offlineTimes []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int, usedGas *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "sealEpoch", offlineTimes, offlineBlocks, uptimes, originatedTxsFee, usedGas) -} - -// SealEpoch is a paid mutator transaction binding the contract method 0x592fe0c0. -// -// Solidity: function sealEpoch(uint256[] offlineTimes, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee, uint256 usedGas) returns() -func (_Contract *ContractSession) SealEpoch(offlineTimes []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int, usedGas *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpoch(&_Contract.TransactOpts, offlineTimes, offlineBlocks, uptimes, originatedTxsFee, usedGas) -} - -// SealEpoch is a paid mutator transaction binding the contract method 0x592fe0c0. -// -// Solidity: function sealEpoch(uint256[] offlineTimes, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee, uint256 usedGas) returns() -func (_Contract *ContractTransactorSession) SealEpoch(offlineTimes []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int, usedGas *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpoch(&_Contract.TransactOpts, offlineTimes, offlineBlocks, uptimes, originatedTxsFee, usedGas) -} - -// SealEpochValidators is a paid mutator transaction binding the contract method 0xe08d7e66. -// -// Solidity: function sealEpochValidators(uint256[] nextValidatorIDs) returns() -func (_Contract *ContractTransactor) SealEpochValidators(opts *bind.TransactOpts, nextValidatorIDs []*big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "sealEpochValidators", nextValidatorIDs) -} - -// SealEpochValidators is a paid mutator transaction binding the contract method 0xe08d7e66. -// -// Solidity: function sealEpochValidators(uint256[] nextValidatorIDs) returns() -func (_Contract *ContractSession) SealEpochValidators(nextValidatorIDs []*big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpochValidators(&_Contract.TransactOpts, nextValidatorIDs) -} - -// SealEpochValidators is a paid mutator transaction binding the contract method 0xe08d7e66. -// -// Solidity: function sealEpochValidators(uint256[] nextValidatorIDs) returns() -func (_Contract *ContractTransactorSession) SealEpochValidators(nextValidatorIDs []*big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpochValidators(&_Contract.TransactOpts, nextValidatorIDs) -} - -// SetGenesisDelegation is a paid mutator transaction binding the contract method 0x18f628d4. -// -// Solidity: function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake, uint256 lockedStake, uint256 lockupFromEpoch, uint256 lockupEndTime, uint256 lockupDuration, uint256 earlyUnlockPenalty, uint256 rewards) returns() -func (_Contract *ContractTransactor) SetGenesisDelegation(opts *bind.TransactOpts, delegator common.Address, toValidatorID *big.Int, stake *big.Int, lockedStake *big.Int, lockupFromEpoch *big.Int, lockupEndTime *big.Int, lockupDuration *big.Int, earlyUnlockPenalty *big.Int, rewards *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "setGenesisDelegation", delegator, toValidatorID, stake, lockedStake, lockupFromEpoch, lockupEndTime, lockupDuration, earlyUnlockPenalty, rewards) -} - -// SetGenesisDelegation is a paid mutator transaction binding the contract method 0x18f628d4. -// -// Solidity: function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake, uint256 lockedStake, uint256 lockupFromEpoch, uint256 lockupEndTime, uint256 lockupDuration, uint256 earlyUnlockPenalty, uint256 rewards) returns() -func (_Contract *ContractSession) SetGenesisDelegation(delegator common.Address, toValidatorID *big.Int, stake *big.Int, lockedStake *big.Int, lockupFromEpoch *big.Int, lockupEndTime *big.Int, lockupDuration *big.Int, earlyUnlockPenalty *big.Int, rewards *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisDelegation(&_Contract.TransactOpts, delegator, toValidatorID, stake, lockedStake, lockupFromEpoch, lockupEndTime, lockupDuration, earlyUnlockPenalty, rewards) -} - -// SetGenesisDelegation is a paid mutator transaction binding the contract method 0x18f628d4. -// -// Solidity: function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake, uint256 lockedStake, uint256 lockupFromEpoch, uint256 lockupEndTime, uint256 lockupDuration, uint256 earlyUnlockPenalty, uint256 rewards) returns() -func (_Contract *ContractTransactorSession) SetGenesisDelegation(delegator common.Address, toValidatorID *big.Int, stake *big.Int, lockedStake *big.Int, lockupFromEpoch *big.Int, lockupEndTime *big.Int, lockupDuration *big.Int, earlyUnlockPenalty *big.Int, rewards *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisDelegation(&_Contract.TransactOpts, delegator, toValidatorID, stake, lockedStake, lockupFromEpoch, lockupEndTime, lockupDuration, earlyUnlockPenalty, rewards) -} - -// SetGenesisValidator is a paid mutator transaction binding the contract method 0x4feb92f3. -// -// Solidity: function setGenesisValidator(address _auth, uint256 validatorID, bytes pubkey, uint256 status, uint256 createdEpoch, uint256 createdTime, uint256 deactivatedEpoch, uint256 deactivatedTime) returns() -func (_Contract *ContractTransactor) SetGenesisValidator(opts *bind.TransactOpts, _auth common.Address, validatorID *big.Int, pubkey []byte, status *big.Int, createdEpoch *big.Int, createdTime *big.Int, deactivatedEpoch *big.Int, deactivatedTime *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "setGenesisValidator", _auth, validatorID, pubkey, status, createdEpoch, createdTime, deactivatedEpoch, deactivatedTime) -} - -// SetGenesisValidator is a paid mutator transaction binding the contract method 0x4feb92f3. -// -// Solidity: function setGenesisValidator(address _auth, uint256 validatorID, bytes pubkey, uint256 status, uint256 createdEpoch, uint256 createdTime, uint256 deactivatedEpoch, uint256 deactivatedTime) returns() -func (_Contract *ContractSession) SetGenesisValidator(_auth common.Address, validatorID *big.Int, pubkey []byte, status *big.Int, createdEpoch *big.Int, createdTime *big.Int, deactivatedEpoch *big.Int, deactivatedTime *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisValidator(&_Contract.TransactOpts, _auth, validatorID, pubkey, status, createdEpoch, createdTime, deactivatedEpoch, deactivatedTime) -} - -// SetGenesisValidator is a paid mutator transaction binding the contract method 0x4feb92f3. -// -// Solidity: function setGenesisValidator(address _auth, uint256 validatorID, bytes pubkey, uint256 status, uint256 createdEpoch, uint256 createdTime, uint256 deactivatedEpoch, uint256 deactivatedTime) returns() -func (_Contract *ContractTransactorSession) SetGenesisValidator(_auth common.Address, validatorID *big.Int, pubkey []byte, status *big.Int, createdEpoch *big.Int, createdTime *big.Int, deactivatedEpoch *big.Int, deactivatedTime *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisValidator(&_Contract.TransactOpts, _auth, validatorID, pubkey, status, createdEpoch, createdTime, deactivatedEpoch, deactivatedTime) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Contract *ContractTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferOwnership", newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Contract *ContractSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Contract.Contract.TransferOwnership(&_Contract.TransactOpts, newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Contract *ContractTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Contract.Contract.TransferOwnership(&_Contract.TransactOpts, newOwner) -} - -// UpdateMinGasPrice is a paid mutator transaction binding the contract method 0x07aaf344. -// -// Solidity: function updateMinGasPrice(uint256 minGasPrice) returns() -func (_Contract *ContractTransactor) UpdateMinGasPrice(opts *bind.TransactOpts, minGasPrice *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateMinGasPrice", minGasPrice) -} - -// UpdateMinGasPrice is a paid mutator transaction binding the contract method 0x07aaf344. -// -// Solidity: function updateMinGasPrice(uint256 minGasPrice) returns() -func (_Contract *ContractSession) UpdateMinGasPrice(minGasPrice *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateMinGasPrice(&_Contract.TransactOpts, minGasPrice) -} - -// UpdateMinGasPrice is a paid mutator transaction binding the contract method 0x07aaf344. -// -// Solidity: function updateMinGasPrice(uint256 minGasPrice) returns() -func (_Contract *ContractTransactorSession) UpdateMinGasPrice(minGasPrice *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateMinGasPrice(&_Contract.TransactOpts, minGasPrice) -} - -// UpdateNetworkRules is a paid mutator transaction binding the contract method 0xb9cc6b1c. -// -// Solidity: function updateNetworkRules(bytes diff) returns() -func (_Contract *ContractTransactor) UpdateNetworkRules(opts *bind.TransactOpts, diff []byte) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateNetworkRules", diff) -} - -// UpdateNetworkRules is a paid mutator transaction binding the contract method 0xb9cc6b1c. -// -// Solidity: function updateNetworkRules(bytes diff) returns() -func (_Contract *ContractSession) UpdateNetworkRules(diff []byte) (*types.Transaction, error) { - return _Contract.Contract.UpdateNetworkRules(&_Contract.TransactOpts, diff) -} - -// UpdateNetworkRules is a paid mutator transaction binding the contract method 0xb9cc6b1c. -// -// Solidity: function updateNetworkRules(bytes diff) returns() -func (_Contract *ContractTransactorSession) UpdateNetworkRules(diff []byte) (*types.Transaction, error) { - return _Contract.Contract.UpdateNetworkRules(&_Contract.TransactOpts, diff) -} - -// UpdateNetworkVersion is a paid mutator transaction binding the contract method 0x267ab446. -// -// Solidity: function updateNetworkVersion(uint256 version) returns() -func (_Contract *ContractTransactor) UpdateNetworkVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateNetworkVersion", version) -} - -// UpdateNetworkVersion is a paid mutator transaction binding the contract method 0x267ab446. -// -// Solidity: function updateNetworkVersion(uint256 version) returns() -func (_Contract *ContractSession) UpdateNetworkVersion(version *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateNetworkVersion(&_Contract.TransactOpts, version) -} - -// UpdateNetworkVersion is a paid mutator transaction binding the contract method 0x267ab446. -// -// Solidity: function updateNetworkVersion(uint256 version) returns() -func (_Contract *ContractTransactorSession) UpdateNetworkVersion(version *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateNetworkVersion(&_Contract.TransactOpts, version) -} - -// UpdateValidatorPubkey is a paid mutator transaction binding the contract method 0x242a6e3f. -// -// Solidity: function updateValidatorPubkey(uint256 validatorID, bytes pubkey) returns() -func (_Contract *ContractTransactor) UpdateValidatorPubkey(opts *bind.TransactOpts, validatorID *big.Int, pubkey []byte) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateValidatorPubkey", validatorID, pubkey) -} - -// UpdateValidatorPubkey is a paid mutator transaction binding the contract method 0x242a6e3f. -// -// Solidity: function updateValidatorPubkey(uint256 validatorID, bytes pubkey) returns() -func (_Contract *ContractSession) UpdateValidatorPubkey(validatorID *big.Int, pubkey []byte) (*types.Transaction, error) { - return _Contract.Contract.UpdateValidatorPubkey(&_Contract.TransactOpts, validatorID, pubkey) -} - -// UpdateValidatorPubkey is a paid mutator transaction binding the contract method 0x242a6e3f. -// -// Solidity: function updateValidatorPubkey(uint256 validatorID, bytes pubkey) returns() -func (_Contract *ContractTransactorSession) UpdateValidatorPubkey(validatorID *big.Int, pubkey []byte) (*types.Transaction, error) { - return _Contract.Contract.UpdateValidatorPubkey(&_Contract.TransactOpts, validatorID, pubkey) -} - -// UpdateValidatorWeight is a paid mutator transaction binding the contract method 0xa4066fbe. -// -// Solidity: function updateValidatorWeight(uint256 validatorID, uint256 value) returns() -func (_Contract *ContractTransactor) UpdateValidatorWeight(opts *bind.TransactOpts, validatorID *big.Int, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateValidatorWeight", validatorID, value) -} - -// UpdateValidatorWeight is a paid mutator transaction binding the contract method 0xa4066fbe. -// -// Solidity: function updateValidatorWeight(uint256 validatorID, uint256 value) returns() -func (_Contract *ContractSession) UpdateValidatorWeight(validatorID *big.Int, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateValidatorWeight(&_Contract.TransactOpts, validatorID, value) -} - -// UpdateValidatorWeight is a paid mutator transaction binding the contract method 0xa4066fbe. -// -// Solidity: function updateValidatorWeight(uint256 validatorID, uint256 value) returns() -func (_Contract *ContractTransactorSession) UpdateValidatorWeight(validatorID *big.Int, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateValidatorWeight(&_Contract.TransactOpts, validatorID, value) -} - -// UpgradeCode is a paid mutator transaction binding the contract method 0xfd1b6ec1. -// -// Solidity: function upgradeCode(address acc, address from) returns() -func (_Contract *ContractTransactor) UpgradeCode(opts *bind.TransactOpts, acc common.Address, from common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "upgradeCode", acc, from) -} - -// UpgradeCode is a paid mutator transaction binding the contract method 0xfd1b6ec1. -// -// Solidity: function upgradeCode(address acc, address from) returns() -func (_Contract *ContractSession) UpgradeCode(acc common.Address, from common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpgradeCode(&_Contract.TransactOpts, acc, from) -} - -// UpgradeCode is a paid mutator transaction binding the contract method 0xfd1b6ec1. -// -// Solidity: function upgradeCode(address acc, address from) returns() -func (_Contract *ContractTransactorSession) UpgradeCode(acc common.Address, from common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpgradeCode(&_Contract.TransactOpts, acc, from) -} - -// ContractOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Contract contract. -type ContractOwnershipTransferredIterator struct { - Event *ContractOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractOwnershipTransferredIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractOwnershipTransferred represents a OwnershipTransferred event raised by the Contract contract. -type ContractOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Contract *ContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ContractOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return &ContractOwnershipTransferredIterator{contract: _Contract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Contract *ContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ContractOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractOwnershipTransferred) - if err := _Contract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Contract *ContractFilterer) ParseOwnershipTransferred(log types.Log) (*ContractOwnershipTransferred, error) { - event := new(ContractOwnershipTransferred) - if err := _Contract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -var ContractBinRuntime = "0x608060405234801561001057600080fd5b506004361061018d5760003560e01c806366e7ea0f116100e3578063b9cc6b1c1161008c578063e08d7e6611610066578063e08d7e6614610702578063f2fde38b14610772578063fd1b6ec1146107985761018d565b8063b9cc6b1c1461062c578063c0c53b8b1461069c578063d6a0c7af146106d45761018d565b80638da5cb5b116100bd5780638da5cb5b146105c95780638f32d59b146105ed578063a4066fbe146106095761018d565b806366e7ea0f14610569578063715018a61461059557806379bead381461059d5761018d565b8063242a6e3f116101455780634ddaf8f21161011f5780634ddaf8f21461033f5780634feb92f314610365578063592fe0c0146104035761018d565b8063242a6e3f14610285578063267ab446146102fc5780634b64e492146103195761018d565b806318f628d41161017657806318f628d4146101ce5780631cef4fab146102265780631e702f83146102625761018d565b806307aaf344146101925780630aeeca00146101b1575b600080fd5b6101af600480360360208110156101a857600080fd5b50356107c6565b005b6101af600480360360208110156101c757600080fd5b5035610969565b6101af60048036036101208110156101e557600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e0810135906101000135610a28565b6101af6004803603608081101561023c57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610b35565b6101af6004803603604081101561027857600080fd5b5080359060200135610ba0565b6101af6004803603604081101561029b57600080fd5b813591908101906040810160208201356401000000008111156102bd57600080fd5b8201836020820111156102cf57600080fd5b803590602001918460018302840111640100000000831117156102f157600080fd5b509092509050610c72565b6101af6004803603602081101561031257600080fd5b5035610d87565b6101af6004803603602081101561032f57600080fd5b50356001600160a01b0316610e46565b6101af6004803603602081101561035557600080fd5b50356001600160a01b0316610ed1565b6101af600480360361010081101561037c57600080fd5b6001600160a01b03823516916020810135918101906060810160408201356401000000008111156103ac57600080fd5b8201836020820111156103be57600080fd5b803590602001918460018302840111640100000000831117156103e057600080fd5b919350915080359060208101359060408101359060608101359060800135610f91565b6101af600480360360a081101561041957600080fd5b81019060208101813564010000000081111561043457600080fd5b82018360208201111561044657600080fd5b8035906020019184602083028401116401000000008311171561046857600080fd5b91939092909160208101903564010000000081111561048657600080fd5b82018360208201111561049857600080fd5b803590602001918460208302840111640100000000831117156104ba57600080fd5b9193909290916020810190356401000000008111156104d857600080fd5b8201836020820111156104ea57600080fd5b8035906020019184602083028401116401000000008311171561050c57600080fd5b91939092909160208101903564010000000081111561052a57600080fd5b82018360208201111561053c57600080fd5b8035906020019184602083028401116401000000008311171561055e57600080fd5b9193509150356110ab565b6101af6004803603604081101561057f57600080fd5b506001600160a01b038135169060200135611270565b6101af611394565b6101af600480360360408110156105b357600080fd5b506001600160a01b03813516906020013561144f565b6105d1611516565b604080516001600160a01b039092168252519081900360200190f35b6105f5611525565b604080519115158252519081900360200190f35b6101af6004803603604081101561061f57600080fd5b5080359060200135611536565b6101af6004803603602081101561064257600080fd5b81019060208101813564010000000081111561065d57600080fd5b82018360208201111561066f57600080fd5b8035906020019184600183028401116401000000008311171561069157600080fd5b509092509050611602565b6101af600480360360608110156106b257600080fd5b506001600160a01b0381358116916020810135821691604090910135166116eb565b6101af600480360360408110156106ea57600080fd5b506001600160a01b0381358116916020013516611838565b6101af6004803603602081101561071857600080fd5b81019060208101813564010000000081111561073357600080fd5b82018360208201111561074557600080fd5b8035906020019184602083028401116401000000008311171561076757600080fd5b509092509050611900565b6101af6004803603602081101561078857600080fd5b50356001600160a01b03166119df565b6101af600480360360408110156107ae57600080fd5b506001600160a01b0381358116916020013516611a41565b6066546001600160a01b03163314610825576040805162461bcd60e51b815260206004820152601e60248201527f63616c6c6572206973206e6f74207468652053464320636f6e74726163740000604482015290519081900360640190fd5b60675460408051808201909152601a81527f7b2245636f6e6f6d79223a7b224d696e4761735072696365223a00000000000060208201526001600160a01b039091169063b9cc6b1c906108b69061087b85611b04565b6040518060400160405280600281526020017f7d7d000000000000000000000000000000000000000000000000000000000000815250611c28565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109025781810151838201526020016108ea565b50505050905090810190601f16801561092f5780820380516001836020036101000a031916815260200191505b5092505050600060405180830381600087803b15801561094e57600080fd5b505af1158015610962573d6000803e3d6000fd5b5050505050565b610971611525565b6109c2576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517f0aeeca000000000000000000000000000000000000000000000000000000000081526004810184905290516001600160a01b0390921691630aeeca009160248082019260009290919082900301818387803b15801561094e57600080fd5b6067546001600160a01b03163314610a715760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b606654604080517f18f628d40000000000000000000000000000000000000000000000000000000081526001600160a01b038c81166004830152602482018c9052604482018b9052606482018a90526084820189905260a4820188905260c4820187905260e482018690526101048201859052915191909216916318f628d49161012480830192600092919082900301818387803b158015610b1257600080fd5b505af1158015610b26573d6000803e3d6000fd5b50505050505050505050505050565b610b3d611525565b610b8e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610b9a84848484611dc6565b50505050565b6067546001600160a01b03163314610be95760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b606654604080517f1e702f83000000000000000000000000000000000000000000000000000000008152600481018590526024810184905290516001600160a01b0390921691631e702f839160448082019260009290919082900301818387803b158015610c5657600080fd5b505af1158015610c6a573d6000803e3d6000fd5b505050505050565b6066546001600160a01b03163314610cd1576040805162461bcd60e51b815260206004820152601e60248201527f63616c6c6572206973206e6f74207468652053464320636f6e74726163740000604482015290519081900360640190fd5b606754604080517f242a6e3f0000000000000000000000000000000000000000000000000000000081526004810186815260248201928352604482018590526001600160a01b039093169263242a6e3f928792879287929091606401848480828437600081840152601f19601f820116905080830192505050945050505050600060405180830381600087803b158015610d6a57600080fd5b505af1158015610d7e573d6000803e3d6000fd5b50505050505050565b610d8f611525565b610de0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517f267ab4460000000000000000000000000000000000000000000000000000000081526004810184905290516001600160a01b039092169163267ab4469160248082019260009290919082900301818387803b15801561094e57600080fd5b610e4e611525565b610e9f576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610ece81610eab611516565b610eb430611ef0565b606754610ec9906001600160a01b0316611ef0565b611dc6565b50565b610ed9611525565b610f2a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517fda7fc24f0000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301529151919092169163da7fc24f91602480830192600092919082900301818387803b15801561094e57600080fd5b6067546001600160a01b03163314610fda5760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b606660009054906101000a90046001600160a01b03166001600160a01b0316634feb92f38a8a8a8a8a8a8a8a8a6040518a63ffffffff1660e01b8152600401808a6001600160a01b03166001600160a01b03168152602001898152602001806020018781526020018681526020018581526020018481526020018381526020018281038252898982818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b158015610b1257600080fd5b6067546001600160a01b031633146110f45760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b606660009054906101000a90046001600160a01b03166001600160a01b031663592fe0c08a8a8a8a8a8a8a8a8a6040518a63ffffffff1660e01b8152600401808060200180602001806020018060200186815260200185810385528e8e82818152602001925060200280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910186810385528c8152602090810191508d908d0280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910186810384528a8152602090810191508b908b0280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169091018681038352888152602090810191508990890280828437600081840152601f19601f8201169050808301925050509d5050505050505050505050505050600060405180830381600087803b158015610b1257600080fd5b6066546001600160a01b031633146112cf576040805162461bcd60e51b815260206004820152601e60248201527f63616c6c6572206973206e6f74207468652053464320636f6e74726163740000604482015290519081900360640190fd5b6066546001600160a01b0383811691161461131b5760405162461bcd60e51b81526004018080602001828103825260218152602001806121ef6021913960400191505060405180910390fd5b6067546001600160a01b039081169063e30443bc908490611345908216318563ffffffff611ef416565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610c5657600080fd5b61139c611525565b6113ed576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b611457611525565b6114a8576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517f79bead380000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052915191909216916379bead3891604480830192600092919082900301818387803b158015610c5657600080fd5b6033546001600160a01b031690565b6033546001600160a01b0316331490565b6066546001600160a01b03163314611595576040805162461bcd60e51b815260206004820152601e60248201527f63616c6c6572206973206e6f74207468652053464320636f6e74726163740000604482015290519081900360640190fd5b606754604080517fa4066fbe000000000000000000000000000000000000000000000000000000008152600481018590526024810184905290516001600160a01b039092169163a4066fbe9160448082019260009290919082900301818387803b158015610c5657600080fd5b61160a611525565b61165b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6067546040517fb9cc6b1c000000000000000000000000000000000000000000000000000000008152602060048201908152602482018490526001600160a01b039092169163b9cc6b1c91859185918190604401848480828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015610c5657600080fd5b600054610100900460ff16806117045750611704611f55565b80611712575060005460ff16155b61174d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806121c1602e913960400191505060405180910390fd5b600054610100900460ff161580156117b357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b6117bc82611f5b565b606780546001600160a01b038086167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560668054928716929091169190911790558015610b9a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550505050565b611840611525565b611891576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606754604080517fd6a0c7af0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015284811660248301529151919092169163d6a0c7af91604480830192600092919082900301818387803b158015610c5657600080fd5b6067546001600160a01b031633146119495760405162461bcd60e51b81526004018080602001828103825260258152602001806122106025913960400191505060405180910390fd5b6066546040517fe08d7e66000000000000000000000000000000000000000000000000000000008152602060048201818152602483018590526001600160a01b039093169263e08d7e6692869286929182916044909101908590850280828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015610c5657600080fd5b6119e7611525565b611a38576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610ece816120bd565b611a49611525565b611a9a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b611aa382612176565b8015611ab35750611ab381612176565b611891576040805162461bcd60e51b815260206004820152600e60248201527f6e6f74206120636f6e7472616374000000000000000000000000000000000000604482015290519081900360640190fd5b606081611b45575060408051808201909152600181527f30000000000000000000000000000000000000000000000000000000000000006020820152611c23565b6000611b508361217c565b90506060816040519080825280601f01601f191660200182016040528015611b7f576020820181803883390190505b5090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015b8415611c1e57600a850660300160f81b828281518110611bc257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a850494507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611ba6565b509150505b919050565b60608084905060608490506060849050606081518351855101016040519080825280601f01601f191660200182016040528015611c6c576020820181803883390190505b509050806000805b8651811015611cdd57868181518110611c8957fe5b602001015160f81c60f81b838380600101945081518110611ca657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c74565b5060005b8551811015611d4a57858181518110611cf657fe5b602001015160f81c60f81b838380600101945081518110611d1357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611ce1565b5060005b8451811015611db757848181518110611d6357fe5b602001015160f81c60f81b838380600101945081518110611d8057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611d4e565b50909998505050505050505050565b611dcf846120bd565b836001600160a01b031663614619546040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e0a57600080fd5b505af1158015611e1e573d6000803e3d6000fd5b50505050611e2b836120bd565b81611e3530611ef0565b14611e87576040805162461bcd60e51b815260206004820152601c60248201527f73656c6620636f6465206861736820646f65736e2774206d6174636800000000604482015290519081900360640190fd5b6067548190611e9e906001600160a01b0316611ef0565b14610b9a576040805162461bcd60e51b815260206004820152601e60248201527f64726976657220636f6465206861736820646f65736e2774206d617463680000604482015290519081900360640190fd5b3f90565b600082820183811015611f4e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b303b1590565b600054610100900460ff1680611f745750611f74611f55565b80611f82575060005460ff16155b611fbd5760405162461bcd60e51b815260040180806020018281038252602e8152602001806121c1602e913960400191505060405180910390fd5b600054610100900460ff1615801561202357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156120b957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b6001600160a01b0381166121025760405162461bcd60e51b815260040180806020018281038252602681526020018061219b6026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b3b151590565b6000805b821561219457600101600a83049250612180565b9291505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564726563697069656e74206973206e6f74207468652053464320636f6e747261637463616c6c6572206973206e6f7420746865204e6f646544726976657220636f6e7472616374a265627a7a72315820e32e2bd9d4306bc53a2f1341ed34b7c36a48a87713cbfbf664b6cde5edf9f98e64736f6c63430005110032" diff --git a/evm/go-x1/gossip/contract/netinit100/contract.go b/evm/go-x1/gossip/contract/netinit100/contract.go deleted file mode 100644 index 654d2bb..0000000 --- a/evm/go-x1/gossip/contract/netinit100/contract.go +++ /dev/null @@ -1,225 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package netinit100 - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// ContractMetaData contains all meta data concerning the Contract contract. -var ContractMetaData = &bind.MetaData{ - ABI: "[{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"sealedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"},{\"internalType\":\"addresspayable\",\"name\":\"_sfc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_lib\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_auth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_driver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_evmWriter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"initializeAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b506126a1806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806329e83e2914610030575b600080fd5b610098600480360361010081101561004757600080fd5b5080359060208101359073ffffffffffffffffffffffffffffffffffffffff60408201358116916060810135821691608082013581169160a081013582169160c082013581169160e001351661009a565b005b604080517f485cc95500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152848116602483015291519185169163485cc9559160448082019260009290919082900301818387803b15801561011357600080fd5b505af1158015610127573d6000803e3d6000fd5b5050604080517fc0c53b8b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a81166004830152878116602483015285811660448301529151918816935063c0c53b8b925060648082019260009290919082900301818387803b1580156101ac57600080fd5b505af11580156101c0573d6000803e3d6000fd5b5050505060006040516101d290610ade565b604051809103906000f0801580156101ee573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561023957600080fd5b505af115801561024d573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663866c4b176969e10de76676d08000006040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166381ffcdf16102ea610ad2565b6010026040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561032357600080fd5b505af1158015610337573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632ee711326064610361610ad2565b600f028161036b57fe5b046040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156103a257600080fd5b505af11580156103b6573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632bb9fe8d60646103e0610ad2565b601402816103ea57fe5b046040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561042157600080fd5b505af1158015610435573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663f8d5177e606461045f610ad2565b600a028161046957fe5b046040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156104a057600080fd5b505af11580156104b4573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16637945ef9960646104de610ad2565b601e02816104e857fe5b046040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561051f57600080fd5b505af1158015610533573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663bf25338b621275006040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561058d57600080fd5b505af11580156105a1573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663ad7b3f7b6301e133806040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156105fc57600080fd5b505af1158015610610573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16638f078bfa60036040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561066857600080fd5b505af115801561067c573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663455366a462093a806040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156106d657600080fd5b505af11580156106ea573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663b6d9edd5672508fab977b917d06040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561074957600080fd5b505af115801561075d573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16636348ebb8620697806040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156107b757600080fd5b505af11580156107cb573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632e84e8e66103e86040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561082457600080fd5b505af1158015610838573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166343326867621e84806040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561089257600080fd5b505af11580156108a6573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663d3f48dbe610e106040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156108ff57600080fd5b505af1158015610913573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166302b769a164746a5288006040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561096f57600080fd5b505af1158015610983573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b5050604080517f10e51e14000000000000000000000000000000000000000000000000000000008152600481018d9052602481018c905273ffffffffffffffffffffffffffffffffffffffff89811660448301528a81166064830152858116608483015286811660a48301529151918b1693506310e51e14925060c48082019260009290919082900301818387803b158015610ab557600080fd5b505af1158015610ac9573d6000803e3d6000fd5b50600092505050ff5b670de0b6b3a764000090565b611b8180610aec8339019056fe608060405234801561001057600080fd5b50611b61806100206000396000f3fe608060405234801561001057600080fd5b50600436106102765760003560e01c80637945ef9911610160578063ad7b3f7b116100d8578063c74dd6211161008c578063d9a7c1f911610071578063d9a7c1f914610517578063f2fde38b1461051f578063f8d5177e1461055257610276565b8063c74dd621146104f2578063d3f48dbe146104fa57610276565b8063b82b8427116100bd578063b82b8427146104c5578063bf25338b146104cd578063c5f530af146104ea57610276565b8063ad7b3f7b1461048b578063b6d9edd5146104a857610276565b80638da5cb5b1161012f5780638f32d59b116101145780638f32d59b1461045f57806394c3e9141461047b578063a77865151461048357610276565b80638da5cb5b146104115780638f078bfa1461044257610276565b80637945ef99146103b25780638129fc1c146103cf57806381ffcdf1146103d7578063866c4b17146103f457610276565b806338eca546116101f35780635a68f01a116101c25780636348ebb8116101a75780636348ebb814610385578063650acd66146103a2578063715018a6146103aa57610276565b80635a68f01a146103755780635e2308d21461037d57610276565b806338eca5461461032b5780633a3ef66c14610333578063433268671461033b578063455366a41461035857610276565b80632265f2841161024a5780632c8c36a51161022f5780632c8c36a5146102e95780632e84e8e6146102f15780632ee711321461030e57610276565b80632265f284146102c45780632bb9fe8d146102cc57610276565b8062cc7f831461027b57806302b769a1146102955780630d4955e3146102b45780630d7b2609146102bc575b600080fd5b61028361056f565b60408051918252519081900360200190f35b6102b2600480360360208110156102ab57600080fd5b5035610575565b005b610283610684565b61028361068a565b610283610690565b6102b2600480360360208110156102e257600080fd5b5035610696565b61028361075a565b6102b26004803603602081101561030757600080fd5b5035610760565b6102b26004803603602081101561032457600080fd5b503561086c565b610283610930565b610283610936565b6102b26004803603602081101561035157600080fd5b503561093c565b6102b26004803603602081101561036e57600080fd5b5035610a4b565b610283610b59565b610283610b5f565b6102b26004803603602081101561039b57600080fd5b5035610b65565b610283610c73565b6102b2610c79565b6102b2600480360360208110156103c857600080fd5b5035610d41565b6102b2610e6e565b6102b2600480360360208110156103ed57600080fd5b5035610f71565b6102b26004803603602081101561040a57600080fd5b503561108a565b6104196111a7565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6102b26004803603602081101561045857600080fd5b50356111c3565b6104676112cd565b604080519115158252519081900360200190f35b6102836112eb565b6102836112f1565b6102b2600480360360208110156104a157600080fd5b50356112f7565b6102b2600480360360208110156104be57600080fd5b5035611406565b61028361151f565b6102b2600480360360208110156104e357600080fd5b5035611525565b610283611633565b610283611639565b6102b26004803603602081101561051057600080fd5b503561163f565b61028361174b565b6102b26004803603602081101561053557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611751565b6102b26004803603602081101561056857600080fd5b50356117b3565b60725481565b61057d6112cd565b6105ce576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001811015610624576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b6509184e72a00081111561067f576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607555565b606d5481565b606c5481565b60675481565b61069e6112cd565b6106ef576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60026106f9611877565b8161070057fe5b04811115610755576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606955565b60745481565b6107686112cd565b6107b9576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606481101561080f576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b620f4240811115610867576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607155565b6108746112cd565b6108c5576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60026108cf611877565b816108d657fe5b0481111561092b576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606855565b60755481565b60735481565b6109446112cd565b610995576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b620f42408110156109ed576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b631dcd6500811115610a46576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607355565b610a536112cd565b610aa4576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b62015180811015610afc576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b62278d00811115610b54576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606f55565b60715481565b606b5481565b610b6d6112cd565b610bbe576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b62015180811015610c16576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b620d2f00811115610c6e576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607255565b606e5481565b610c816112cd565b610cd2576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60335460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b610d496112cd565b610d9a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6064610da4611877565b60050281610dae57fe5b04811015610e03576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b6002610e0d611877565b81610e1457fe5b04811115610e69576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606b55565b600054610100900460ff1680610e875750610e87611883565b80610e95575060005460ff16155b610ed05760405162461bcd60e51b815260040180806020018281038252602e815260200180611aff602e913960400191505060405180910390fd5b600054610100900460ff16158015610f3657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b610f3f33611889565b8015610f6e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50565b610f796112cd565b610fca576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610fd2611877565b811015611026576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b61102e611877565b601f02811115611085576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606755565b6110926112cd565b6110e3576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b69152d02c7e14af6800000811015611142576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b6a084595161401484a0000008111156111a2576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606655565b60335473ffffffffffffffffffffffffffffffffffffffff1690565b6111cb6112cd565b61121c576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6002811015611272576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b60648111156112c8576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606e55565b60335473ffffffffffffffffffffffffffffffffffffffff16331490565b606a5481565b60685481565b6112ff6112cd565b611350576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b62278d008110156113a8576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b630784ce00811115611401576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606d55565b61140e6112cd565b61145f576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6706f05b59d3b200008110156114bc576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b6801bc16d674ec80000081111561151a576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607055565b606f5481565b61152d6112cd565b61157e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b620151808110156115d6576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b62278d0081111561162e576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606c55565b60665481565b60695481565b6116476112cd565b611698576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60648110156116ee576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b620d2f00811115611746576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607455565b60705481565b6117596112cd565b6117aa576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610f6e816119f8565b6117bb6112cd565b61180c576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6002611816611877565b8161181d57fe5b04811115611872576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606a55565b670de0b6b3a764000090565b303b1590565b600054610100900460ff16806118a257506118a2611883565b806118b0575060005460ff16155b6118eb5760405162461bcd60e51b815260040180806020018281038252602e815260200180611aff602e913960400191505060405180910390fd5b600054610100900460ff1615801561195157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156119f457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b73ffffffffffffffffffffffffffffffffffffffff8116611a4a5760405162461bcd60e51b8152600401808060200182810382526026815260200180611ad96026913960400191505060405180910390fd5b60335460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905556fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a265627a7a72315820a66ff1d0075ebc7eff9c2e0ad68fcc90ad880a3accd69c8990de69bb6643eb1964736f6c63430005110032a265627a7a72315820fcecf216ff5beb5aad4fb1a418703d008592779b9404dec9428d69d97c7de14764736f6c63430005110032", -} - -// ContractABI is the input ABI used to generate the binding from. -// Deprecated: Use ContractMetaData.ABI instead. -var ContractABI = ContractMetaData.ABI - -// ContractBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ContractMetaData.Bin instead. -var ContractBin = ContractMetaData.Bin - -// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. -func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Contract, error) { - parsed, err := ContractMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// Contract is an auto generated Go binding around an Ethereum contract. -type Contract struct { - ContractCaller // Read-only binding to the contract - ContractTransactor // Write-only binding to the contract - ContractFilterer // Log filterer for contract events -} - -// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. -type ContractCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ContractTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ContractFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ContractSession struct { - Contract *Contract // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ContractCallerSession struct { - Contract *ContractCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ContractTransactorSession struct { - Contract *ContractTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. -type ContractRaw struct { - Contract *Contract // Generic contract binding to access the raw methods on -} - -// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ContractCallerRaw struct { - Contract *ContractCaller // Generic read-only contract binding to access the raw methods on -} - -// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ContractTransactorRaw struct { - Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewContract creates a new instance of Contract, bound to a specific deployed contract. -func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { - contract, err := bindContract(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. -func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { - contract, err := bindContract(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ContractCaller{contract: contract}, nil -} - -// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. -func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { - contract, err := bindContract(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ContractTransactor{contract: contract}, nil -} - -// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. -func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { - contract, err := bindContract(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ContractFilterer{contract: contract}, nil -} - -// bindContract binds a generic wrapper to an already deployed contract. -func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ContractABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.contract.Transact(opts, method, params...) -} - -// InitializeAll is a paid mutator transaction binding the contract method 0x29e83e29. -// -// Solidity: function initializeAll(uint256 sealedEpoch, uint256 totalSupply, address _sfc, address _lib, address _auth, address _driver, address _evmWriter, address _owner) returns() -func (_Contract *ContractTransactor) InitializeAll(opts *bind.TransactOpts, sealedEpoch *big.Int, totalSupply *big.Int, _sfc common.Address, _lib common.Address, _auth common.Address, _driver common.Address, _evmWriter common.Address, _owner common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "initializeAll", sealedEpoch, totalSupply, _sfc, _lib, _auth, _driver, _evmWriter, _owner) -} - -// InitializeAll is a paid mutator transaction binding the contract method 0x29e83e29. -// -// Solidity: function initializeAll(uint256 sealedEpoch, uint256 totalSupply, address _sfc, address _lib, address _auth, address _driver, address _evmWriter, address _owner) returns() -func (_Contract *ContractSession) InitializeAll(sealedEpoch *big.Int, totalSupply *big.Int, _sfc common.Address, _lib common.Address, _auth common.Address, _driver common.Address, _evmWriter common.Address, _owner common.Address) (*types.Transaction, error) { - return _Contract.Contract.InitializeAll(&_Contract.TransactOpts, sealedEpoch, totalSupply, _sfc, _lib, _auth, _driver, _evmWriter, _owner) -} - -// InitializeAll is a paid mutator transaction binding the contract method 0x29e83e29. -// -// Solidity: function initializeAll(uint256 sealedEpoch, uint256 totalSupply, address _sfc, address _lib, address _auth, address _driver, address _evmWriter, address _owner) returns() -func (_Contract *ContractTransactorSession) InitializeAll(sealedEpoch *big.Int, totalSupply *big.Int, _sfc common.Address, _lib common.Address, _auth common.Address, _driver common.Address, _evmWriter common.Address, _owner common.Address) (*types.Transaction, error) { - return _Contract.Contract.InitializeAll(&_Contract.TransactOpts, sealedEpoch, totalSupply, _sfc, _lib, _auth, _driver, _evmWriter, _owner) -} - -var ContractBinRuntime = "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c806329e83e2914610030575b600080fd5b610098600480360361010081101561004757600080fd5b5080359060208101359073ffffffffffffffffffffffffffffffffffffffff60408201358116916060810135821691608082013581169160a081013582169160c082013581169160e001351661009a565b005b604080517f485cc95500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152848116602483015291519185169163485cc9559160448082019260009290919082900301818387803b15801561011357600080fd5b505af1158015610127573d6000803e3d6000fd5b5050604080517fc0c53b8b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a81166004830152878116602483015285811660448301529151918816935063c0c53b8b925060648082019260009290919082900301818387803b1580156101ac57600080fd5b505af11580156101c0573d6000803e3d6000fd5b5050505060006040516101d290610ade565b604051809103906000f0801580156101ee573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561023957600080fd5b505af115801561024d573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663866c4b176969e10de76676d08000006040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166381ffcdf16102ea610ad2565b6010026040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561032357600080fd5b505af1158015610337573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632ee711326064610361610ad2565b600f028161036b57fe5b046040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156103a257600080fd5b505af11580156103b6573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632bb9fe8d60646103e0610ad2565b601402816103ea57fe5b046040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561042157600080fd5b505af1158015610435573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663f8d5177e606461045f610ad2565b600a028161046957fe5b046040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156104a057600080fd5b505af11580156104b4573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16637945ef9960646104de610ad2565b601e02816104e857fe5b046040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561051f57600080fd5b505af1158015610533573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663bf25338b621275006040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561058d57600080fd5b505af11580156105a1573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663ad7b3f7b6301e133806040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156105fc57600080fd5b505af1158015610610573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16638f078bfa60036040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561066857600080fd5b505af115801561067c573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663455366a462093a806040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156106d657600080fd5b505af11580156106ea573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663b6d9edd5672508fab977b917d06040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561074957600080fd5b505af115801561075d573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16636348ebb8620697806040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156107b757600080fd5b505af11580156107cb573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632e84e8e66103e86040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561082457600080fd5b505af1158015610838573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166343326867621e84806040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561089257600080fd5b505af11580156108a6573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663d3f48dbe610e106040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156108ff57600080fd5b505af1158015610913573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166302b769a164746a5288006040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561096f57600080fd5b505af1158015610983573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b5050604080517f10e51e14000000000000000000000000000000000000000000000000000000008152600481018d9052602481018c905273ffffffffffffffffffffffffffffffffffffffff89811660448301528a81166064830152858116608483015286811660a48301529151918b1693506310e51e14925060c48082019260009290919082900301818387803b158015610ab557600080fd5b505af1158015610ac9573d6000803e3d6000fd5b50600092505050ff5b670de0b6b3a764000090565b611b8180610aec8339019056fe608060405234801561001057600080fd5b50611b61806100206000396000f3fe608060405234801561001057600080fd5b50600436106102765760003560e01c80637945ef9911610160578063ad7b3f7b116100d8578063c74dd6211161008c578063d9a7c1f911610071578063d9a7c1f914610517578063f2fde38b1461051f578063f8d5177e1461055257610276565b8063c74dd621146104f2578063d3f48dbe146104fa57610276565b8063b82b8427116100bd578063b82b8427146104c5578063bf25338b146104cd578063c5f530af146104ea57610276565b8063ad7b3f7b1461048b578063b6d9edd5146104a857610276565b80638da5cb5b1161012f5780638f32d59b116101145780638f32d59b1461045f57806394c3e9141461047b578063a77865151461048357610276565b80638da5cb5b146104115780638f078bfa1461044257610276565b80637945ef99146103b25780638129fc1c146103cf57806381ffcdf1146103d7578063866c4b17146103f457610276565b806338eca546116101f35780635a68f01a116101c25780636348ebb8116101a75780636348ebb814610385578063650acd66146103a2578063715018a6146103aa57610276565b80635a68f01a146103755780635e2308d21461037d57610276565b806338eca5461461032b5780633a3ef66c14610333578063433268671461033b578063455366a41461035857610276565b80632265f2841161024a5780632c8c36a51161022f5780632c8c36a5146102e95780632e84e8e6146102f15780632ee711321461030e57610276565b80632265f284146102c45780632bb9fe8d146102cc57610276565b8062cc7f831461027b57806302b769a1146102955780630d4955e3146102b45780630d7b2609146102bc575b600080fd5b61028361056f565b60408051918252519081900360200190f35b6102b2600480360360208110156102ab57600080fd5b5035610575565b005b610283610684565b61028361068a565b610283610690565b6102b2600480360360208110156102e257600080fd5b5035610696565b61028361075a565b6102b26004803603602081101561030757600080fd5b5035610760565b6102b26004803603602081101561032457600080fd5b503561086c565b610283610930565b610283610936565b6102b26004803603602081101561035157600080fd5b503561093c565b6102b26004803603602081101561036e57600080fd5b5035610a4b565b610283610b59565b610283610b5f565b6102b26004803603602081101561039b57600080fd5b5035610b65565b610283610c73565b6102b2610c79565b6102b2600480360360208110156103c857600080fd5b5035610d41565b6102b2610e6e565b6102b2600480360360208110156103ed57600080fd5b5035610f71565b6102b26004803603602081101561040a57600080fd5b503561108a565b6104196111a7565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6102b26004803603602081101561045857600080fd5b50356111c3565b6104676112cd565b604080519115158252519081900360200190f35b6102836112eb565b6102836112f1565b6102b2600480360360208110156104a157600080fd5b50356112f7565b6102b2600480360360208110156104be57600080fd5b5035611406565b61028361151f565b6102b2600480360360208110156104e357600080fd5b5035611525565b610283611633565b610283611639565b6102b26004803603602081101561051057600080fd5b503561163f565b61028361174b565b6102b26004803603602081101561053557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611751565b6102b26004803603602081101561056857600080fd5b50356117b3565b60725481565b61057d6112cd565b6105ce576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001811015610624576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b6509184e72a00081111561067f576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607555565b606d5481565b606c5481565b60675481565b61069e6112cd565b6106ef576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60026106f9611877565b8161070057fe5b04811115610755576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606955565b60745481565b6107686112cd565b6107b9576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b606481101561080f576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b620f4240811115610867576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607155565b6108746112cd565b6108c5576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60026108cf611877565b816108d657fe5b0481111561092b576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606855565b60755481565b60735481565b6109446112cd565b610995576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b620f42408110156109ed576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b631dcd6500811115610a46576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607355565b610a536112cd565b610aa4576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b62015180811015610afc576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b62278d00811115610b54576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606f55565b60715481565b606b5481565b610b6d6112cd565b610bbe576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b62015180811015610c16576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b620d2f00811115610c6e576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607255565b606e5481565b610c816112cd565b610cd2576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60335460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b610d496112cd565b610d9a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6064610da4611877565b60050281610dae57fe5b04811015610e03576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b6002610e0d611877565b81610e1457fe5b04811115610e69576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606b55565b600054610100900460ff1680610e875750610e87611883565b80610e95575060005460ff16155b610ed05760405162461bcd60e51b815260040180806020018281038252602e815260200180611aff602e913960400191505060405180910390fd5b600054610100900460ff16158015610f3657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b610f3f33611889565b8015610f6e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50565b610f796112cd565b610fca576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610fd2611877565b811015611026576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b61102e611877565b601f02811115611085576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606755565b6110926112cd565b6110e3576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b69152d02c7e14af6800000811015611142576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b6a084595161401484a0000008111156111a2576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606655565b60335473ffffffffffffffffffffffffffffffffffffffff1690565b6111cb6112cd565b61121c576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6002811015611272576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b60648111156112c8576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606e55565b60335473ffffffffffffffffffffffffffffffffffffffff16331490565b606a5481565b60685481565b6112ff6112cd565b611350576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b62278d008110156113a8576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b630784ce00811115611401576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606d55565b61140e6112cd565b61145f576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6706f05b59d3b200008110156114bc576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b6801bc16d674ec80000081111561151a576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607055565b606f5481565b61152d6112cd565b61157e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b620151808110156115d6576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b62278d0081111561162e576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606c55565b60665481565b60695481565b6116476112cd565b611698576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60648110156116ee576040805162461bcd60e51b815260206004820152600f60248201527f746f6f20736d616c6c2076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b620d2f00811115611746576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b607455565b60705481565b6117596112cd565b6117aa576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b610f6e816119f8565b6117bb6112cd565b61180c576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6002611816611877565b8161181d57fe5b04811115611872576040805162461bcd60e51b815260206004820152600f60248201527f746f6f206c617267652076616c75650000000000000000000000000000000000604482015290519081900360640190fd5b606a55565b670de0b6b3a764000090565b303b1590565b600054610100900460ff16806118a257506118a2611883565b806118b0575060005460ff16155b6118eb5760405162461bcd60e51b815260040180806020018281038252602e815260200180611aff602e913960400191505060405180910390fd5b600054610100900460ff1615801561195157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156119f457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b73ffffffffffffffffffffffffffffffffffffffff8116611a4a5760405162461bcd60e51b8152600401808060200182810382526026815260200180611ad96026913960400191505060405180910390fd5b60335460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905556fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a265627a7a72315820a66ff1d0075ebc7eff9c2e0ad68fcc90ad880a3accd69c8990de69bb6643eb1964736f6c63430005110032a265627a7a72315820fcecf216ff5beb5aad4fb1a418703d008592779b9404dec9428d69d97c7de14764736f6c63430005110032" diff --git a/evm/go-x1/gossip/contract/sfc100/contract.go b/evm/go-x1/gossip/contract/sfc100/contract.go deleted file mode 100644 index 8a0c3b5..0000000 --- a/evm/go-x1/gossip/contract/sfc100/contract.go +++ /dev/null @@ -1,2146 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package sfc100 - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// ContractMetaData contains all meta data concerning the Contract contract. -var ContractMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"}],\"name\":\"ChangedValidatorStatus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deactivatedEpoch\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deactivatedTime\",\"type\":\"uint256\"}],\"name\":\"DeactivatedValidator\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"UpdatedBaseRewardPerSec\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blocksNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"period\",\"type\":\"uint256\"}],\"name\":\"UpdatedOfflinePenaltyThreshold\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"syncPubkey\",\"type\":\"bool\"}],\"name\":\"_syncValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"currentEpoch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"currentSealedEpoch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getEpochSnapshot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"epochFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalBaseRewardWeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalTxRewardWeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseRewardPerSecond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"getLockedStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getLockupInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"lockedStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fromEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getStashedLockupRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"lockupExtraReward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupBaseReward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlockedReward\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getValidator\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receivedStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdTime\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"auth\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"getValidatorID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getValidatorPubkey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getWithdrawalRequest\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"isLockedUp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"lastValidatorID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minGasPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"slashingRefundRatio\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"stakeTokenizerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"stashedRewardsUntilEpoch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalActiveStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSlashedStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"bytes3\",\"name\":\"\",\"type\":\"bytes3\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"voteBookAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"sealedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_totalSupply\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"nodeDriver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"lib\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_c\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"updateStakeTokenizerAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"v\",\"type\":\"address\"}],\"name\":\"updateLibAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"v\",\"type\":\"address\"}],\"name\":\"updateTreasuryAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"v\",\"type\":\"address\"}],\"name\":\"updateConstsAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"constsAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"v\",\"type\":\"address\"}],\"name\":\"updateVoteBookAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"offlineTime\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"offlineBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"uptimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"originatedTxsFee\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"epochGas\",\"type\":\"uint256\"}],\"name\":\"sealEpoch\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nextValidatorIDs\",\"type\":\"uint256[]\"}],\"name\":\"sealEpochValidators\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b506134a3806100206000396000f3fe6080604052600436106102855760003560e01c80638b0e9f3f11610153578063c65ee0e1116100cb578063d46fa5181161007f578063e08d7e6611610064578063e08d7e6614610b1f578063e6f45adf14610b9c578063f2fde38b14610bcf57610285565b8063d46fa51814610af5578063d96ed50514610b0a57610285565b8063cc8343aa116100b0578063cc8343aa14610a51578063cfd4766314610a83578063cfdbb7cd14610abc57610285565b8063c65ee0e114610a12578063c7be95de14610a3c57610285565b8063a2f6e6bc11610122578063b5d8962711610107578063b5d8962714610959578063b810e411146109c4578063c5f956af146109fd57610285565b8063a2f6e6bc146108ed578063a86a056f1461092057610285565b80638b0e9f3f1461083b5780638da5cb5b146108505780638f32d59b1461086557806396c7ee461461088e57610285565b8063592fe0c0116102015780637cacb1d6116101b5578063854873e11161019a578063854873e114610754578063860c2750146107f3578063893675c61461082657610285565b80637cacb1d61461070c578063841e45611461072157610285565b8063670322f8116101e6578063670322f8146106a9578063715018a6146106e257806376671808146106f757610285565b8063592fe0c0146105215780635fab23a81461069457610285565b80631f2701521161025857806339b80c001161023d57806339b80c001461044257806354fd4d50146104a4578063550359a0146104ee57610285565b80631f270152146103d057806328f731481461042d57610285565b80630135b1db146102ee5780630e559d821461033357806310e51e141461036457806318160ddd146103bb575b366102d7576040805162461bcd60e51b815260206004820152601560248201527f7472616e7366657273206e6f7420616c6c6f7765640000000000000000000000604482015290519081900360640190fd5b6080546102ec906001600160a01b0316610c02565b005b3480156102fa57600080fd5b506103216004803603602081101561031157600080fd5b50356001600160a01b0316610c2b565b60408051918252519081900360200190f35b34801561033f57600080fd5b50610348610c3d565b604080516001600160a01b039092168252519081900360200190f35b34801561037057600080fd5b506102ec600480360360c081101561038757600080fd5b508035906020810135906001600160a01b0360408201358116916060810135821691608082013581169160a0013516610c4c565b3480156103c757600080fd5b50610321610e50565b3480156103dc57600080fd5b5061040f600480360360608110156103f357600080fd5b506001600160a01b038135169060208101359060400135610e56565b60408051938452602084019290925282820152519081900360600190f35b34801561043957600080fd5b50610321610e88565b34801561044e57600080fd5b5061046c6004803603602081101561046557600080fd5b5035610e8e565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b3480156104b057600080fd5b506104b9610ed0565b604080517fffffff00000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b3480156104fa57600080fd5b506102ec6004803603602081101561051157600080fd5b50356001600160a01b0316610ef5565b34801561052d57600080fd5b506102ec600480360360a081101561054457600080fd5b81019060208101813564010000000081111561055f57600080fd5b82018360208201111561057157600080fd5b8035906020019184602083028401116401000000008311171561059357600080fd5b9193909290916020810190356401000000008111156105b157600080fd5b8201836020820111156105c357600080fd5b803590602001918460208302840111640100000000831117156105e557600080fd5b91939092909160208101903564010000000081111561060357600080fd5b82018360208201111561061557600080fd5b8035906020019184602083028401116401000000008311171561063757600080fd5b91939092909160208101903564010000000081111561065557600080fd5b82018360208201111561066757600080fd5b8035906020019184602083028401116401000000008311171561068957600080fd5b919350915035610f88565b3480156106a057600080fd5b50610321611243565b3480156106b557600080fd5b50610321600480360360408110156106cc57600080fd5b506001600160a01b038135169060200135611249565b3480156106ee57600080fd5b506102ec61128d565b34801561070357600080fd5b50610321611348565b34801561071857600080fd5b50610321611351565b34801561072d57600080fd5b506102ec6004803603602081101561074457600080fd5b50356001600160a01b0316611357565b34801561076057600080fd5b5061077e6004803603602081101561077757600080fd5b50356113ea565b6040805160208082528351818301528351919283929083019185019080838360005b838110156107b85781810151838201526020016107a0565b50505050905090810190601f1680156107e55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156107ff57600080fd5b506102ec6004803603602081101561081657600080fd5b50356001600160a01b03166114a3565b34801561083257600080fd5b50610348611536565b34801561084757600080fd5b50610321611545565b34801561085c57600080fd5b5061034861154b565b34801561087157600080fd5b5061087a61155a565b604080519115158252519081900360200190f35b34801561089a57600080fd5b506108c7600480360360408110156108b157600080fd5b506001600160a01b03813516906020013561156b565b604080519485526020850193909352838301919091526060830152519081900360800190f35b3480156108f957600080fd5b506102ec6004803603602081101561091057600080fd5b50356001600160a01b031661159d565b34801561092c57600080fd5b506103216004803603604081101561094357600080fd5b506001600160a01b038135169060200135611630565b34801561096557600080fd5b506109836004803603602081101561097c57600080fd5b503561164d565b604080519788526020880196909652868601949094526060860192909252608085015260a08401526001600160a01b031660c0830152519081900360e00190f35b3480156109d057600080fd5b5061040f600480360360408110156109e757600080fd5b506001600160a01b038135169060200135611693565b348015610a0957600080fd5b506103486116bf565b348015610a1e57600080fd5b5061032160048036036020811015610a3557600080fd5b50356116ce565b348015610a4857600080fd5b506103216116e0565b348015610a5d57600080fd5b506102ec60048036036040811015610a7457600080fd5b508035906020013515156116e6565b348015610a8f57600080fd5b5061032160048036036040811015610aa657600080fd5b506001600160a01b038135169060200135611915565b348015610ac857600080fd5b5061087a60048036036040811015610adf57600080fd5b506001600160a01b038135169060200135611932565b348015610b0157600080fd5b506103486119c9565b348015610b1657600080fd5b506103216119d8565b348015610b2b57600080fd5b506102ec60048036036020811015610b4257600080fd5b810190602081018135640100000000811115610b5d57600080fd5b820183602082011115610b6f57600080fd5b80359060200191846020830284011164010000000083111715610b9157600080fd5b5090925090506119de565b348015610ba857600080fd5b506102ec60048036036020811015610bbf57600080fd5b50356001600160a01b0316611b22565b348015610bdb57600080fd5b506102ec60048036036020811015610bf257600080fd5b50356001600160a01b0316611bb5565b3660008037600080366000845af43d6000803e808015610c21573d6000f35b3d6000fd5b505050565b60696020526000908152604090205481565b607b546001600160a01b031681565b600054610100900460ff1680610c655750610c65611c1a565b80610c73575060005460ff16155b610cae5760405162461bcd60e51b815260040180806020018281038252602e815260200180613441602e913960400191505060405180910390fd5b600054610100900460ff16158015610d1457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b610d1d82611c20565b6067879055606680546001600160a01b038088167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556080805487841690831617905560818054868416921691909117908190556076889055604080517f38eca546000000000000000000000000000000000000000000000000000000008152905191909216916338eca546916004808301926020929190829003018186803b158015610dcf57600080fd5b505afa158015610de3573d6000803e3d6000fd5b505050506040513d6020811015610df957600080fd5b5051607e55610e06611d82565b6000888152607760205260409020600701558015610e4757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050505050565b60765481565b607160209081526000938452604080852082529284528284209052825290208054600182015460029092015490919083565b606d5481565b607760205280600052604060002060009150905080600701549080600801549080600901549080600a01549080600b01549080600c01549080600d0154905087565b7f33303400000000000000000000000000000000000000000000000000000000005b90565b610efd61155a565b610f4e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b608280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b610f9133611d86565b610fcc5760405162461bcd60e51b81526004018080602001828103825260298152602001806133f76029913960400191505060405180910390fd5b600060776000610fda611348565b8152602001908152602001600020905060608160060180548060200260200160405190810160405280929190818152602001828054801561103a57602002820191906000526020600020905b815481526020019060010190808311611026575b505050505090506110c182828d8d80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508c8c80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d9d92505050565b606754600090815260776020526040902060078101546001906110e2611d82565b11156110f95781600701546110f5611d82565b0390505b61117b818584868d8d80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508c8c80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611fa492505050565b611185818661278e565b505061118f611348565b60675561119a611d82565b6007830155608154604080517fd9a7c1f900000000000000000000000000000000000000000000000000000000815290516001600160a01b039092169163d9a7c1f991600480820192602092909190829003018186803b1580156111fd57600080fd5b505afa158015611211573d6000803e3d6000fd5b505050506040513d602081101561122757600080fd5b5051600b83015550607654600d90910155505050505050505050565b606e5481565b60006112558383611932565b61126157506000611287565b506001600160a01b03821660009081526073602090815260408083208484529091529020545b92915050565b61129561155a565b6112e6576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b60675460010190565b60675481565b61135f61155a565b6113b0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b607f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b606a6020908152600091825260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001861615020190931692909204918201849004840281018401909452808452909183018282801561149b5780601f106114705761010080835404028352916020019161149b565b820191906000526020600020905b81548152906001019060200180831161147e57829003601f168201915b505050505081565b6114ab61155a565b6114fc576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b608180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6082546001600160a01b031681565b606c5481565b6033546001600160a01b031690565b6033546001600160a01b0316331490565b607360209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b6115a561155a565b6115f6576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b607b80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b607060209081526000928352604080842090915290825290205481565b606860205260009081526040902080546001820154600283015460038401546004850154600586015460069096015494959394929391929091906001600160a01b031687565b607460209081526000928352604080842090915290825290208054600182015460029092015490919083565b607f546001600160a01b031681565b607a6020526000908152604090205481565b606b5481565b6116ef82612981565b611740576040805162461bcd60e51b815260206004820152601760248201527f76616c696461746f7220646f65736e2774206578697374000000000000000000604482015290519081900360640190fd5b6000828152606860205260409020600381015490541561175e575060005b606654604080517fa4066fbe000000000000000000000000000000000000000000000000000000008152600481018690526024810184905290516001600160a01b039092169163a4066fbe9160448082019260009290919082900301818387803b1580156117cb57600080fd5b505af11580156117df573d6000803e3d6000fd5b505050508180156117ef57508015155b15610c26576066546000848152606a60205260409081902081517f242a6e3f0000000000000000000000000000000000000000000000000000000081526004810187815260248201938452825460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001831615610100020190911604604483018190526001600160a01b039095169463242a6e3f948994939091606490910190849080156118e05780601f106118b5576101008083540402835291602001916118e0565b820191906000526020600020905b8154815290600101906020018083116118c357829003601f168201915b50509350505050600060405180830381600087803b15801561190157600080fd5b505af1158015610e47573d6000803e3d6000fd5b607260209081526000928352604080842090915290825290205481565b6001600160a01b03821660009081526073602090815260408083208484529091528120600201541580159061198957506001600160a01b038316600090815260736020908152604080832085845290915290205415155b80156119c257506001600160a01b03831660009081526073602090815260408083208584529091529020600201546119bf611d82565b11155b9392505050565b6081546001600160a01b031690565b607e5481565b6119e733611d86565b611a225760405162461bcd60e51b81526004018080602001828103825260298152602001806133f76029913960400191505060405180910390fd5b600060776000611a30611348565b8152602001908152602001600020905060008090505b82811015611aa9576000848483818110611a5c57fe5b60209081029290920135600081815260688452604080822060030154948890529020839055600c860154909350611a9a91508263ffffffff61299816565b600c8501555050600101611a46565b50611ab860068201848461331f565b50606654607e54604080517f07aaf3440000000000000000000000000000000000000000000000000000000081526004810192909252516001600160a01b03909216916307aaf3449160248082019260009290919082900301818387803b15801561190157600080fd5b611b2a61155a565b611b7b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b608080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b611bbd61155a565b611c0e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b611c17816129f2565b50565b303b1590565b600054610100900460ff1680611c395750611c39611c1a565b80611c47575060005460ff16155b611c825760405162461bcd60e51b815260040180806020018281038252602e815260200180613441602e913960400191505060405180910390fd5b600054610100900460ff16158015611ce857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611d7e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b4290565b6066546001600160a01b038281169116145b919050565b60005b8351811015611f9d57608160009054906101000a90046001600160a01b03166001600160a01b0316635a68f01a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611df757600080fd5b505afa158015611e0b573d6000803e3d6000fd5b505050506040513d6020811015611e2157600080fd5b50518251839083908110611e3157fe5b6020026020010151118015611ed35750608160009054906101000a90046001600160a01b03166001600160a01b031662cc7f836040518163ffffffff1660e01b815260040160206040518083038186803b158015611e8e57600080fd5b505afa158015611ea2573d6000803e3d6000fd5b505050506040513d6020811015611eb857600080fd5b50518351849083908110611ec857fe5b602002602001015110155b15611f1457611ef6848281518110611ee757fe5b60200260200101516008612aab565b611f14848281518110611f0557fe5b602002602001015160006116e6565b828181518110611f2057fe5b6020026020010151856004016000868481518110611f3a57fe5b6020026020010151815260200190815260200160002081905550818181518110611f6057fe5b6020026020010151856005016000868481518110611f7a57fe5b602090810291909101810151825281019190915260400160002055600101611da0565b5050505050565b611fac613366565b6040518060a001604052808551604051908082528060200260200182016040528015611fe2578160200160208202803883390190505b50815260200160008152602001855160405190808252806020026020018201604052801561201a578160200160208202803883390190505b508152602001600081526020016000815250905060008090505b845181101561213557600086600301600087848151811061205157fe5b6020026020010151815260200190815260200160002054905060008090508185848151811061207c57fe5b602002602001015111156120a3578185848151811061209757fe5b60200260200101510390505b898684815181106120b057fe5b60200260200101518202816120c157fe5b04846040015184815181106120d257fe5b60200260200101818152505061210c846040015184815181106120f157fe5b6020026020010151856060015161299890919063ffffffff16565b60608501526080840151612126908263ffffffff61299816565b60808501525050600101612034565b5060005b84518110156121fe578784828151811061214f57fe5b60200260200101518986848151811061216457fe5b60200260200101518a60000160008a878151811061217e57fe5b6020026020010151815260200190815260200160002054028161219d57fe5b0402816121a657fe5b04826000015182815181106121b757fe5b6020026020010181815250506121f1826000015182815181106121d657fe5b6020026020010151836020015161299890919063ffffffff16565b6020830152600101612139565b5060005b845181101561263d5760006122ab89608160009054906101000a90046001600160a01b03166001600160a01b031663d9a7c1f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561225f57600080fd5b505afa158015612273573d6000803e3d6000fd5b505050506040513d602081101561228957600080fd5b5051855180518690811061229957fe5b60200260200101518660200151612bd5565b90506122e76122da8460800151856040015185815181106122c857fe5b60200260200101518660600151612c24565b829063ffffffff61299816565b905060008683815181106122f757fe5b60209081029190910181015160008181526068835260408082206006015460815482517fa778651500000000000000000000000000000000000000000000000000000000815292519496506001600160a01b039182169593946123ad948994929093169263a77865159260048082019391829003018186803b15801561237c57600080fd5b505afa158015612390573d6000803e3d6000fd5b505050506040513d60208110156123a657600080fd5b5051612d8d565b6001600160a01b03831660009081526072602090815260408083208784529091529020549091508015612554576000816123e78587611249565b8402816123f057fe5b0490508083036123fe613395565b6001600160a01b03861660009081526073602090815260408083208a8452909152902060030154612430908490612daa565b905061243a613395565b612445836000612daa565b6001600160a01b0388166000908152606f602090815260408083208c8452825291829020825160608101845281548152600182015492810192909252600201549181019190915290915061249a908383612f6c565b6001600160a01b0388166000818152606f602090815260408083208d84528252808320855181558583015160018083019190915595820151600291820155938352607482528083208d845282529182902082516060810184528154815294810154918501919091529091015490820152612515908383612f6c565b6001600160a01b03881660009081526074602090815260408083208c845282529182902083518155908301516001820155910151600290910155505050505b6000848152606860205260408120600301548387039181156125865781612579612f87565b84028161258257fe5b0490505b808e600101600089815260200190815260200160002054018f6001016000898152602001908152602001600020819055508a89815181106125c357fe5b60200260200101518f6003016000898152602001908152602001600020819055508b89815181106125f057fe5b60200260200101518e600201600089815260200190815260200160002054018f60020160008981526020019081526020016000208190555050505050505050508080600101915050612202565b50608081015160088701819055602082015160098801556060820151600a880155607654111561267b57600886015460768054919091039055612681565b60006076555b607f546001600160a01b031615610e4757600061269c612f87565b608160009054906101000a90046001600160a01b03166001600160a01b03166394c3e9146040518163ffffffff1660e01b815260040160206040518083038186803b1580156126ea57600080fd5b505afa1580156126fe573d6000803e3d6000fd5b505050506040513d602081101561271457600080fd5b50516080840151028161272357fe5b04905061272f81612f93565b607f546040516001600160a01b03909116908290600081818185875af1925050503d806000811461277c576040519150601f19603f3d011682016040523d82523d6000602084013e612781565b606091505b5050505050505050505050565b608154604080517f3a3ef66c00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b031691633a3ef66c916004808301926020929190829003018186803b1580156127ec57600080fd5b505afa158015612800573d6000803e3d6000fd5b505050506040513d602081101561281657600080fd5b50518302600101905060008161282a612f87565b84028161283357fe5b0490506000608160009054906101000a90046001600160a01b03166001600160a01b0316632c8c36a56040518163ffffffff1660e01b815260040160206040518083038186803b15801561288657600080fd5b505afa15801561289a573d6000803e3d6000fd5b505050506040513d60208110156128b057600080fd5b505190508481016128bf612f87565b820283870201816128cc57fe5b0491506128d882613031565b915060006128e4612f87565b83607e5402816128f057fe5b04905061297681608160009054906101000a90046001600160a01b03166001600160a01b03166338eca5466040518163ffffffff1660e01b815260040160206040518083038186803b15801561294557600080fd5b505afa158015612959573d6000803e3d6000fd5b505050506040513d602081101561296f57600080fd5b505161309f565b607e55505050505050565b600090815260686020526040902060050154151590565b6000828201838110156119c2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038116612a375760405162461bcd60e51b81526004018080602001828103825260268152602001806133d16026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b600082815260686020526040902054158015612ac657508015155b15612af357600082815260686020526040902060030154606d54612aef9163ffffffff6130d416565b606d555b600082815260686020526040902054811115611d7e57600082815260686020526040902081815560020154612b9b57612b2a611348565b600083815260686020526040902060020155612b44611d82565b6000838152606860209081526040918290206001810184905560020154825190815290810192909252805184927fac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e4792908290030190a25b60408051828152905183917fcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e919081900360200190a25050565b600082612be457506000612c1c565b6000612bf6868663ffffffff61311616565b9050612c1883612c0c838763ffffffff61311616565b9063ffffffff61316f16565b9150505b949350505050565b600082612c33575060006119c2565b6000612c4983612c0c878763ffffffff61311616565b9050612d84612c56612f87565b608154604080517f94c3e9140000000000000000000000000000000000000000000000000000000081529051612c0c926001600160a01b0316916394c3e914916004808301926020929190829003018186803b158015612cb557600080fd5b505afa158015612cc9573d6000803e3d6000fd5b505050506040513d6020811015612cdf57600080fd5b5051608154604080517fc74dd62100000000000000000000000000000000000000000000000000000000815290516001600160a01b039092169163c74dd62191600480820192602092909190829003018186803b158015612d3f57600080fd5b505afa158015612d53573d6000803e3d6000fd5b505050506040513d6020811015612d6957600080fd5b5051612d73612f87565b03038461311690919063ffffffff16565b95945050505050565b60006119c2612d9a612f87565b612c0c858563ffffffff61311616565b612db2613395565b60405180606001604052806000815260200160008152602001600081525090506000608160009054906101000a90046001600160a01b03166001600160a01b0316635e2308d26040518163ffffffff1660e01b815260040160206040518083038186803b158015612e2257600080fd5b505afa158015612e36573d6000803e3d6000fd5b505050506040513d6020811015612e4c57600080fd5b505190508215612f4457600081612e61612f87565b0390506000612ef3608160009054906101000a90046001600160a01b03166001600160a01b0316630d4955e36040518163ffffffff1660e01b815260040160206040518083038186803b158015612eb757600080fd5b505afa158015612ecb573d6000803e3d6000fd5b505050506040513d6020811015612ee157600080fd5b5051612c0c848863ffffffff61311616565b90506000612f14612f02612f87565b612c0c8987860163ffffffff61311616565b9050612f31612f21612f87565b612c0c898763ffffffff61311616565b602086018190529003845250612f659050565b612f5f612f4f612f87565b612c0c868463ffffffff61311616565b60408301525b5092915050565b612f74613395565b612c1c612f8185856131b1565b836131b1565b670de0b6b3a764000090565b606654604080517f66e7ea0f0000000000000000000000000000000000000000000000000000000081523060048201526024810184905290516001600160a01b03909216916366e7ea0f9160448082019260009290919082900301818387803b158015612fff57600080fd5b505af1158015613013573d6000803e3d6000fd5b505060765461302b925090508263ffffffff61299816565b60765550565b6000606461303d612f87565b6069028161304757fe5b0482111561306b576064613059612f87565b6069028161306357fe5b049050611d98565b6064613075612f87565b605f028161307f57fe5b0482101561309b576064613091612f87565b605f028161306357fe5b5090565b600066038d7ea4c680008311156130be575066038d7ea4c68000611287565b818310156130cd575080611287565b5090919050565b60006119c283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613223565b60008261312557506000611287565b8282028284828161313257fe5b04146119c25760405162461bcd60e51b81526004018080602001828103825260218152602001806134206021913960400191505060405180910390fd5b60006119c283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506132ba565b6131b9613395565b60408051606081019091528251845182916131da919063ffffffff61299816565b81526020016131fa8460200151866020015161299890919063ffffffff16565b815260200161321a8460400151866040015161299890919063ffffffff16565b90529392505050565b600081848411156132b25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561327757818101518382015260200161325f565b50505050905090810190601f1680156132a45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836133095760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561327757818101518382015260200161325f565b50600083858161331557fe5b0495945050505050565b82805482825590600052602060002090810192821561335a579160200282015b8281111561335a57823582559160200191906001019061333f565b5061309b9291506133b6565b6040518060a0016040528060608152602001600081526020016060815260200160008152602001600081525090565b60405180606001604052806000815260200160008152602001600081525090565b610ef291905b8082111561309b57600081556001016133bc56fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737363616c6c6572206973206e6f7420746865204e6f64654472697665724175746820636f6e7472616374536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a265627a7a723158201ba2eb9163d4b98d4977fa009fb214c9d86da5cc8771883025ff4c7a2ea550d164736f6c63430005110032", -} - -// ContractABI is the input ABI used to generate the binding from. -// Deprecated: Use ContractMetaData.ABI instead. -var ContractABI = ContractMetaData.ABI - -// ContractBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ContractMetaData.Bin instead. -var ContractBin = ContractMetaData.Bin - -// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. -func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Contract, error) { - parsed, err := ContractMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// Contract is an auto generated Go binding around an Ethereum contract. -type Contract struct { - ContractCaller // Read-only binding to the contract - ContractTransactor // Write-only binding to the contract - ContractFilterer // Log filterer for contract events -} - -// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. -type ContractCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ContractTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ContractFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ContractSession struct { - Contract *Contract // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ContractCallerSession struct { - Contract *ContractCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ContractTransactorSession struct { - Contract *ContractTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. -type ContractRaw struct { - Contract *Contract // Generic contract binding to access the raw methods on -} - -// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ContractCallerRaw struct { - Contract *ContractCaller // Generic read-only contract binding to access the raw methods on -} - -// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ContractTransactorRaw struct { - Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewContract creates a new instance of Contract, bound to a specific deployed contract. -func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { - contract, err := bindContract(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. -func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { - contract, err := bindContract(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ContractCaller{contract: contract}, nil -} - -// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. -func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { - contract, err := bindContract(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ContractTransactor{contract: contract}, nil -} - -// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. -func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { - contract, err := bindContract(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ContractFilterer{contract: contract}, nil -} - -// bindContract binds a generic wrapper to an already deployed contract. -func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ContractABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.contract.Transact(opts, method, params...) -} - -// ConstsAddress is a free data retrieval call binding the contract method 0xd46fa518. -// -// Solidity: function constsAddress() view returns(address) -func (_Contract *ContractCaller) ConstsAddress(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "constsAddress") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// ConstsAddress is a free data retrieval call binding the contract method 0xd46fa518. -// -// Solidity: function constsAddress() view returns(address) -func (_Contract *ContractSession) ConstsAddress() (common.Address, error) { - return _Contract.Contract.ConstsAddress(&_Contract.CallOpts) -} - -// ConstsAddress is a free data retrieval call binding the contract method 0xd46fa518. -// -// Solidity: function constsAddress() view returns(address) -func (_Contract *ContractCallerSession) ConstsAddress() (common.Address, error) { - return _Contract.Contract.ConstsAddress(&_Contract.CallOpts) -} - -// CurrentEpoch is a free data retrieval call binding the contract method 0x76671808. -// -// Solidity: function currentEpoch() view returns(uint256) -func (_Contract *ContractCaller) CurrentEpoch(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "currentEpoch") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// CurrentEpoch is a free data retrieval call binding the contract method 0x76671808. -// -// Solidity: function currentEpoch() view returns(uint256) -func (_Contract *ContractSession) CurrentEpoch() (*big.Int, error) { - return _Contract.Contract.CurrentEpoch(&_Contract.CallOpts) -} - -// CurrentEpoch is a free data retrieval call binding the contract method 0x76671808. -// -// Solidity: function currentEpoch() view returns(uint256) -func (_Contract *ContractCallerSession) CurrentEpoch() (*big.Int, error) { - return _Contract.Contract.CurrentEpoch(&_Contract.CallOpts) -} - -// CurrentSealedEpoch is a free data retrieval call binding the contract method 0x7cacb1d6. -// -// Solidity: function currentSealedEpoch() view returns(uint256) -func (_Contract *ContractCaller) CurrentSealedEpoch(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "currentSealedEpoch") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// CurrentSealedEpoch is a free data retrieval call binding the contract method 0x7cacb1d6. -// -// Solidity: function currentSealedEpoch() view returns(uint256) -func (_Contract *ContractSession) CurrentSealedEpoch() (*big.Int, error) { - return _Contract.Contract.CurrentSealedEpoch(&_Contract.CallOpts) -} - -// CurrentSealedEpoch is a free data retrieval call binding the contract method 0x7cacb1d6. -// -// Solidity: function currentSealedEpoch() view returns(uint256) -func (_Contract *ContractCallerSession) CurrentSealedEpoch() (*big.Int, error) { - return _Contract.Contract.CurrentSealedEpoch(&_Contract.CallOpts) -} - -// GetEpochSnapshot is a free data retrieval call binding the contract method 0x39b80c00. -// -// Solidity: function getEpochSnapshot(uint256 ) view returns(uint256 endTime, uint256 epochFee, uint256 totalBaseRewardWeight, uint256 totalTxRewardWeight, uint256 baseRewardPerSecond, uint256 totalStake, uint256 totalSupply) -func (_Contract *ContractCaller) GetEpochSnapshot(opts *bind.CallOpts, arg0 *big.Int) (struct { - EndTime *big.Int - EpochFee *big.Int - TotalBaseRewardWeight *big.Int - TotalTxRewardWeight *big.Int - BaseRewardPerSecond *big.Int - TotalStake *big.Int - TotalSupply *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getEpochSnapshot", arg0) - - outstruct := new(struct { - EndTime *big.Int - EpochFee *big.Int - TotalBaseRewardWeight *big.Int - TotalTxRewardWeight *big.Int - BaseRewardPerSecond *big.Int - TotalStake *big.Int - TotalSupply *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.EndTime = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.EpochFee = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.TotalBaseRewardWeight = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.TotalTxRewardWeight = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - outstruct.BaseRewardPerSecond = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) - outstruct.TotalStake = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) - outstruct.TotalSupply = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// GetEpochSnapshot is a free data retrieval call binding the contract method 0x39b80c00. -// -// Solidity: function getEpochSnapshot(uint256 ) view returns(uint256 endTime, uint256 epochFee, uint256 totalBaseRewardWeight, uint256 totalTxRewardWeight, uint256 baseRewardPerSecond, uint256 totalStake, uint256 totalSupply) -func (_Contract *ContractSession) GetEpochSnapshot(arg0 *big.Int) (struct { - EndTime *big.Int - EpochFee *big.Int - TotalBaseRewardWeight *big.Int - TotalTxRewardWeight *big.Int - BaseRewardPerSecond *big.Int - TotalStake *big.Int - TotalSupply *big.Int -}, error) { - return _Contract.Contract.GetEpochSnapshot(&_Contract.CallOpts, arg0) -} - -// GetEpochSnapshot is a free data retrieval call binding the contract method 0x39b80c00. -// -// Solidity: function getEpochSnapshot(uint256 ) view returns(uint256 endTime, uint256 epochFee, uint256 totalBaseRewardWeight, uint256 totalTxRewardWeight, uint256 baseRewardPerSecond, uint256 totalStake, uint256 totalSupply) -func (_Contract *ContractCallerSession) GetEpochSnapshot(arg0 *big.Int) (struct { - EndTime *big.Int - EpochFee *big.Int - TotalBaseRewardWeight *big.Int - TotalTxRewardWeight *big.Int - BaseRewardPerSecond *big.Int - TotalStake *big.Int - TotalSupply *big.Int -}, error) { - return _Contract.Contract.GetEpochSnapshot(&_Contract.CallOpts, arg0) -} - -// GetLockedStake is a free data retrieval call binding the contract method 0x670322f8. -// -// Solidity: function getLockedStake(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractCaller) GetLockedStake(opts *bind.CallOpts, delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getLockedStake", delegator, toValidatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetLockedStake is a free data retrieval call binding the contract method 0x670322f8. -// -// Solidity: function getLockedStake(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractSession) GetLockedStake(delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetLockedStake(&_Contract.CallOpts, delegator, toValidatorID) -} - -// GetLockedStake is a free data retrieval call binding the contract method 0x670322f8. -// -// Solidity: function getLockedStake(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetLockedStake(delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetLockedStake(&_Contract.CallOpts, delegator, toValidatorID) -} - -// GetLockupInfo is a free data retrieval call binding the contract method 0x96c7ee46. -// -// Solidity: function getLockupInfo(address , uint256 ) view returns(uint256 lockedStake, uint256 fromEpoch, uint256 endTime, uint256 duration) -func (_Contract *ContractCaller) GetLockupInfo(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (struct { - LockedStake *big.Int - FromEpoch *big.Int - EndTime *big.Int - Duration *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getLockupInfo", arg0, arg1) - - outstruct := new(struct { - LockedStake *big.Int - FromEpoch *big.Int - EndTime *big.Int - Duration *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.LockedStake = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.FromEpoch = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.EndTime = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.Duration = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// GetLockupInfo is a free data retrieval call binding the contract method 0x96c7ee46. -// -// Solidity: function getLockupInfo(address , uint256 ) view returns(uint256 lockedStake, uint256 fromEpoch, uint256 endTime, uint256 duration) -func (_Contract *ContractSession) GetLockupInfo(arg0 common.Address, arg1 *big.Int) (struct { - LockedStake *big.Int - FromEpoch *big.Int - EndTime *big.Int - Duration *big.Int -}, error) { - return _Contract.Contract.GetLockupInfo(&_Contract.CallOpts, arg0, arg1) -} - -// GetLockupInfo is a free data retrieval call binding the contract method 0x96c7ee46. -// -// Solidity: function getLockupInfo(address , uint256 ) view returns(uint256 lockedStake, uint256 fromEpoch, uint256 endTime, uint256 duration) -func (_Contract *ContractCallerSession) GetLockupInfo(arg0 common.Address, arg1 *big.Int) (struct { - LockedStake *big.Int - FromEpoch *big.Int - EndTime *big.Int - Duration *big.Int -}, error) { - return _Contract.Contract.GetLockupInfo(&_Contract.CallOpts, arg0, arg1) -} - -// GetStake is a free data retrieval call binding the contract method 0xcfd47663. -// -// Solidity: function getStake(address , uint256 ) view returns(uint256) -func (_Contract *ContractCaller) GetStake(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getStake", arg0, arg1) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetStake is a free data retrieval call binding the contract method 0xcfd47663. -// -// Solidity: function getStake(address , uint256 ) view returns(uint256) -func (_Contract *ContractSession) GetStake(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - return _Contract.Contract.GetStake(&_Contract.CallOpts, arg0, arg1) -} - -// GetStake is a free data retrieval call binding the contract method 0xcfd47663. -// -// Solidity: function getStake(address , uint256 ) view returns(uint256) -func (_Contract *ContractCallerSession) GetStake(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - return _Contract.Contract.GetStake(&_Contract.CallOpts, arg0, arg1) -} - -// GetStashedLockupRewards is a free data retrieval call binding the contract method 0xb810e411. -// -// Solidity: function getStashedLockupRewards(address , uint256 ) view returns(uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractCaller) GetStashedLockupRewards(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (struct { - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getStashedLockupRewards", arg0, arg1) - - outstruct := new(struct { - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.LockupExtraReward = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.LockupBaseReward = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.UnlockedReward = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// GetStashedLockupRewards is a free data retrieval call binding the contract method 0xb810e411. -// -// Solidity: function getStashedLockupRewards(address , uint256 ) view returns(uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractSession) GetStashedLockupRewards(arg0 common.Address, arg1 *big.Int) (struct { - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int -}, error) { - return _Contract.Contract.GetStashedLockupRewards(&_Contract.CallOpts, arg0, arg1) -} - -// GetStashedLockupRewards is a free data retrieval call binding the contract method 0xb810e411. -// -// Solidity: function getStashedLockupRewards(address , uint256 ) view returns(uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractCallerSession) GetStashedLockupRewards(arg0 common.Address, arg1 *big.Int) (struct { - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int -}, error) { - return _Contract.Contract.GetStashedLockupRewards(&_Contract.CallOpts, arg0, arg1) -} - -// GetValidator is a free data retrieval call binding the contract method 0xb5d89627. -// -// Solidity: function getValidator(uint256 ) view returns(uint256 status, uint256 deactivatedTime, uint256 deactivatedEpoch, uint256 receivedStake, uint256 createdEpoch, uint256 createdTime, address auth) -func (_Contract *ContractCaller) GetValidator(opts *bind.CallOpts, arg0 *big.Int) (struct { - Status *big.Int - DeactivatedTime *big.Int - DeactivatedEpoch *big.Int - ReceivedStake *big.Int - CreatedEpoch *big.Int - CreatedTime *big.Int - Auth common.Address -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getValidator", arg0) - - outstruct := new(struct { - Status *big.Int - DeactivatedTime *big.Int - DeactivatedEpoch *big.Int - ReceivedStake *big.Int - CreatedEpoch *big.Int - CreatedTime *big.Int - Auth common.Address - }) - if err != nil { - return *outstruct, err - } - - outstruct.Status = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.DeactivatedTime = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.DeactivatedEpoch = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.ReceivedStake = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - outstruct.CreatedEpoch = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) - outstruct.CreatedTime = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) - outstruct.Auth = *abi.ConvertType(out[6], new(common.Address)).(*common.Address) - - return *outstruct, err - -} - -// GetValidator is a free data retrieval call binding the contract method 0xb5d89627. -// -// Solidity: function getValidator(uint256 ) view returns(uint256 status, uint256 deactivatedTime, uint256 deactivatedEpoch, uint256 receivedStake, uint256 createdEpoch, uint256 createdTime, address auth) -func (_Contract *ContractSession) GetValidator(arg0 *big.Int) (struct { - Status *big.Int - DeactivatedTime *big.Int - DeactivatedEpoch *big.Int - ReceivedStake *big.Int - CreatedEpoch *big.Int - CreatedTime *big.Int - Auth common.Address -}, error) { - return _Contract.Contract.GetValidator(&_Contract.CallOpts, arg0) -} - -// GetValidator is a free data retrieval call binding the contract method 0xb5d89627. -// -// Solidity: function getValidator(uint256 ) view returns(uint256 status, uint256 deactivatedTime, uint256 deactivatedEpoch, uint256 receivedStake, uint256 createdEpoch, uint256 createdTime, address auth) -func (_Contract *ContractCallerSession) GetValidator(arg0 *big.Int) (struct { - Status *big.Int - DeactivatedTime *big.Int - DeactivatedEpoch *big.Int - ReceivedStake *big.Int - CreatedEpoch *big.Int - CreatedTime *big.Int - Auth common.Address -}, error) { - return _Contract.Contract.GetValidator(&_Contract.CallOpts, arg0) -} - -// GetValidatorID is a free data retrieval call binding the contract method 0x0135b1db. -// -// Solidity: function getValidatorID(address ) view returns(uint256) -func (_Contract *ContractCaller) GetValidatorID(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getValidatorID", arg0) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetValidatorID is a free data retrieval call binding the contract method 0x0135b1db. -// -// Solidity: function getValidatorID(address ) view returns(uint256) -func (_Contract *ContractSession) GetValidatorID(arg0 common.Address) (*big.Int, error) { - return _Contract.Contract.GetValidatorID(&_Contract.CallOpts, arg0) -} - -// GetValidatorID is a free data retrieval call binding the contract method 0x0135b1db. -// -// Solidity: function getValidatorID(address ) view returns(uint256) -func (_Contract *ContractCallerSession) GetValidatorID(arg0 common.Address) (*big.Int, error) { - return _Contract.Contract.GetValidatorID(&_Contract.CallOpts, arg0) -} - -// GetValidatorPubkey is a free data retrieval call binding the contract method 0x854873e1. -// -// Solidity: function getValidatorPubkey(uint256 ) view returns(bytes) -func (_Contract *ContractCaller) GetValidatorPubkey(opts *bind.CallOpts, arg0 *big.Int) ([]byte, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getValidatorPubkey", arg0) - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -// GetValidatorPubkey is a free data retrieval call binding the contract method 0x854873e1. -// -// Solidity: function getValidatorPubkey(uint256 ) view returns(bytes) -func (_Contract *ContractSession) GetValidatorPubkey(arg0 *big.Int) ([]byte, error) { - return _Contract.Contract.GetValidatorPubkey(&_Contract.CallOpts, arg0) -} - -// GetValidatorPubkey is a free data retrieval call binding the contract method 0x854873e1. -// -// Solidity: function getValidatorPubkey(uint256 ) view returns(bytes) -func (_Contract *ContractCallerSession) GetValidatorPubkey(arg0 *big.Int) ([]byte, error) { - return _Contract.Contract.GetValidatorPubkey(&_Contract.CallOpts, arg0) -} - -// GetWithdrawalRequest is a free data retrieval call binding the contract method 0x1f270152. -// -// Solidity: function getWithdrawalRequest(address , uint256 , uint256 ) view returns(uint256 epoch, uint256 time, uint256 amount) -func (_Contract *ContractCaller) GetWithdrawalRequest(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int, arg2 *big.Int) (struct { - Epoch *big.Int - Time *big.Int - Amount *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getWithdrawalRequest", arg0, arg1, arg2) - - outstruct := new(struct { - Epoch *big.Int - Time *big.Int - Amount *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.Epoch = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.Time = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.Amount = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// GetWithdrawalRequest is a free data retrieval call binding the contract method 0x1f270152. -// -// Solidity: function getWithdrawalRequest(address , uint256 , uint256 ) view returns(uint256 epoch, uint256 time, uint256 amount) -func (_Contract *ContractSession) GetWithdrawalRequest(arg0 common.Address, arg1 *big.Int, arg2 *big.Int) (struct { - Epoch *big.Int - Time *big.Int - Amount *big.Int -}, error) { - return _Contract.Contract.GetWithdrawalRequest(&_Contract.CallOpts, arg0, arg1, arg2) -} - -// GetWithdrawalRequest is a free data retrieval call binding the contract method 0x1f270152. -// -// Solidity: function getWithdrawalRequest(address , uint256 , uint256 ) view returns(uint256 epoch, uint256 time, uint256 amount) -func (_Contract *ContractCallerSession) GetWithdrawalRequest(arg0 common.Address, arg1 *big.Int, arg2 *big.Int) (struct { - Epoch *big.Int - Time *big.Int - Amount *big.Int -}, error) { - return _Contract.Contract.GetWithdrawalRequest(&_Contract.CallOpts, arg0, arg1, arg2) -} - -// IsLockedUp is a free data retrieval call binding the contract method 0xcfdbb7cd. -// -// Solidity: function isLockedUp(address delegator, uint256 toValidatorID) view returns(bool) -func (_Contract *ContractCaller) IsLockedUp(opts *bind.CallOpts, delegator common.Address, toValidatorID *big.Int) (bool, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "isLockedUp", delegator, toValidatorID) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// IsLockedUp is a free data retrieval call binding the contract method 0xcfdbb7cd. -// -// Solidity: function isLockedUp(address delegator, uint256 toValidatorID) view returns(bool) -func (_Contract *ContractSession) IsLockedUp(delegator common.Address, toValidatorID *big.Int) (bool, error) { - return _Contract.Contract.IsLockedUp(&_Contract.CallOpts, delegator, toValidatorID) -} - -// IsLockedUp is a free data retrieval call binding the contract method 0xcfdbb7cd. -// -// Solidity: function isLockedUp(address delegator, uint256 toValidatorID) view returns(bool) -func (_Contract *ContractCallerSession) IsLockedUp(delegator common.Address, toValidatorID *big.Int) (bool, error) { - return _Contract.Contract.IsLockedUp(&_Contract.CallOpts, delegator, toValidatorID) -} - -// IsOwner is a free data retrieval call binding the contract method 0x8f32d59b. -// -// Solidity: function isOwner() view returns(bool) -func (_Contract *ContractCaller) IsOwner(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "isOwner") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// IsOwner is a free data retrieval call binding the contract method 0x8f32d59b. -// -// Solidity: function isOwner() view returns(bool) -func (_Contract *ContractSession) IsOwner() (bool, error) { - return _Contract.Contract.IsOwner(&_Contract.CallOpts) -} - -// IsOwner is a free data retrieval call binding the contract method 0x8f32d59b. -// -// Solidity: function isOwner() view returns(bool) -func (_Contract *ContractCallerSession) IsOwner() (bool, error) { - return _Contract.Contract.IsOwner(&_Contract.CallOpts) -} - -// LastValidatorID is a free data retrieval call binding the contract method 0xc7be95de. -// -// Solidity: function lastValidatorID() view returns(uint256) -func (_Contract *ContractCaller) LastValidatorID(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "lastValidatorID") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// LastValidatorID is a free data retrieval call binding the contract method 0xc7be95de. -// -// Solidity: function lastValidatorID() view returns(uint256) -func (_Contract *ContractSession) LastValidatorID() (*big.Int, error) { - return _Contract.Contract.LastValidatorID(&_Contract.CallOpts) -} - -// LastValidatorID is a free data retrieval call binding the contract method 0xc7be95de. -// -// Solidity: function lastValidatorID() view returns(uint256) -func (_Contract *ContractCallerSession) LastValidatorID() (*big.Int, error) { - return _Contract.Contract.LastValidatorID(&_Contract.CallOpts) -} - -// MinGasPrice is a free data retrieval call binding the contract method 0xd96ed505. -// -// Solidity: function minGasPrice() view returns(uint256) -func (_Contract *ContractCaller) MinGasPrice(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "minGasPrice") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// MinGasPrice is a free data retrieval call binding the contract method 0xd96ed505. -// -// Solidity: function minGasPrice() view returns(uint256) -func (_Contract *ContractSession) MinGasPrice() (*big.Int, error) { - return _Contract.Contract.MinGasPrice(&_Contract.CallOpts) -} - -// MinGasPrice is a free data retrieval call binding the contract method 0xd96ed505. -// -// Solidity: function minGasPrice() view returns(uint256) -func (_Contract *ContractCallerSession) MinGasPrice() (*big.Int, error) { - return _Contract.Contract.MinGasPrice(&_Contract.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Contract *ContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Contract *ContractSession) Owner() (common.Address, error) { - return _Contract.Contract.Owner(&_Contract.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Contract *ContractCallerSession) Owner() (common.Address, error) { - return _Contract.Contract.Owner(&_Contract.CallOpts) -} - -// SlashingRefundRatio is a free data retrieval call binding the contract method 0xc65ee0e1. -// -// Solidity: function slashingRefundRatio(uint256 ) view returns(uint256) -func (_Contract *ContractCaller) SlashingRefundRatio(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "slashingRefundRatio", arg0) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// SlashingRefundRatio is a free data retrieval call binding the contract method 0xc65ee0e1. -// -// Solidity: function slashingRefundRatio(uint256 ) view returns(uint256) -func (_Contract *ContractSession) SlashingRefundRatio(arg0 *big.Int) (*big.Int, error) { - return _Contract.Contract.SlashingRefundRatio(&_Contract.CallOpts, arg0) -} - -// SlashingRefundRatio is a free data retrieval call binding the contract method 0xc65ee0e1. -// -// Solidity: function slashingRefundRatio(uint256 ) view returns(uint256) -func (_Contract *ContractCallerSession) SlashingRefundRatio(arg0 *big.Int) (*big.Int, error) { - return _Contract.Contract.SlashingRefundRatio(&_Contract.CallOpts, arg0) -} - -// StakeTokenizerAddress is a free data retrieval call binding the contract method 0x0e559d82. -// -// Solidity: function stakeTokenizerAddress() view returns(address) -func (_Contract *ContractCaller) StakeTokenizerAddress(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "stakeTokenizerAddress") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// StakeTokenizerAddress is a free data retrieval call binding the contract method 0x0e559d82. -// -// Solidity: function stakeTokenizerAddress() view returns(address) -func (_Contract *ContractSession) StakeTokenizerAddress() (common.Address, error) { - return _Contract.Contract.StakeTokenizerAddress(&_Contract.CallOpts) -} - -// StakeTokenizerAddress is a free data retrieval call binding the contract method 0x0e559d82. -// -// Solidity: function stakeTokenizerAddress() view returns(address) -func (_Contract *ContractCallerSession) StakeTokenizerAddress() (common.Address, error) { - return _Contract.Contract.StakeTokenizerAddress(&_Contract.CallOpts) -} - -// StashedRewardsUntilEpoch is a free data retrieval call binding the contract method 0xa86a056f. -// -// Solidity: function stashedRewardsUntilEpoch(address , uint256 ) view returns(uint256) -func (_Contract *ContractCaller) StashedRewardsUntilEpoch(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "stashedRewardsUntilEpoch", arg0, arg1) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// StashedRewardsUntilEpoch is a free data retrieval call binding the contract method 0xa86a056f. -// -// Solidity: function stashedRewardsUntilEpoch(address , uint256 ) view returns(uint256) -func (_Contract *ContractSession) StashedRewardsUntilEpoch(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - return _Contract.Contract.StashedRewardsUntilEpoch(&_Contract.CallOpts, arg0, arg1) -} - -// StashedRewardsUntilEpoch is a free data retrieval call binding the contract method 0xa86a056f. -// -// Solidity: function stashedRewardsUntilEpoch(address , uint256 ) view returns(uint256) -func (_Contract *ContractCallerSession) StashedRewardsUntilEpoch(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - return _Contract.Contract.StashedRewardsUntilEpoch(&_Contract.CallOpts, arg0, arg1) -} - -// TotalActiveStake is a free data retrieval call binding the contract method 0x28f73148. -// -// Solidity: function totalActiveStake() view returns(uint256) -func (_Contract *ContractCaller) TotalActiveStake(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "totalActiveStake") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalActiveStake is a free data retrieval call binding the contract method 0x28f73148. -// -// Solidity: function totalActiveStake() view returns(uint256) -func (_Contract *ContractSession) TotalActiveStake() (*big.Int, error) { - return _Contract.Contract.TotalActiveStake(&_Contract.CallOpts) -} - -// TotalActiveStake is a free data retrieval call binding the contract method 0x28f73148. -// -// Solidity: function totalActiveStake() view returns(uint256) -func (_Contract *ContractCallerSession) TotalActiveStake() (*big.Int, error) { - return _Contract.Contract.TotalActiveStake(&_Contract.CallOpts) -} - -// TotalSlashedStake is a free data retrieval call binding the contract method 0x5fab23a8. -// -// Solidity: function totalSlashedStake() view returns(uint256) -func (_Contract *ContractCaller) TotalSlashedStake(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "totalSlashedStake") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalSlashedStake is a free data retrieval call binding the contract method 0x5fab23a8. -// -// Solidity: function totalSlashedStake() view returns(uint256) -func (_Contract *ContractSession) TotalSlashedStake() (*big.Int, error) { - return _Contract.Contract.TotalSlashedStake(&_Contract.CallOpts) -} - -// TotalSlashedStake is a free data retrieval call binding the contract method 0x5fab23a8. -// -// Solidity: function totalSlashedStake() view returns(uint256) -func (_Contract *ContractCallerSession) TotalSlashedStake() (*big.Int, error) { - return _Contract.Contract.TotalSlashedStake(&_Contract.CallOpts) -} - -// TotalStake is a free data retrieval call binding the contract method 0x8b0e9f3f. -// -// Solidity: function totalStake() view returns(uint256) -func (_Contract *ContractCaller) TotalStake(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "totalStake") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalStake is a free data retrieval call binding the contract method 0x8b0e9f3f. -// -// Solidity: function totalStake() view returns(uint256) -func (_Contract *ContractSession) TotalStake() (*big.Int, error) { - return _Contract.Contract.TotalStake(&_Contract.CallOpts) -} - -// TotalStake is a free data retrieval call binding the contract method 0x8b0e9f3f. -// -// Solidity: function totalStake() view returns(uint256) -func (_Contract *ContractCallerSession) TotalStake() (*big.Int, error) { - return _Contract.Contract.TotalStake(&_Contract.CallOpts) -} - -// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. -// -// Solidity: function totalSupply() view returns(uint256) -func (_Contract *ContractCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "totalSupply") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. -// -// Solidity: function totalSupply() view returns(uint256) -func (_Contract *ContractSession) TotalSupply() (*big.Int, error) { - return _Contract.Contract.TotalSupply(&_Contract.CallOpts) -} - -// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. -// -// Solidity: function totalSupply() view returns(uint256) -func (_Contract *ContractCallerSession) TotalSupply() (*big.Int, error) { - return _Contract.Contract.TotalSupply(&_Contract.CallOpts) -} - -// TreasuryAddress is a free data retrieval call binding the contract method 0xc5f956af. -// -// Solidity: function treasuryAddress() view returns(address) -func (_Contract *ContractCaller) TreasuryAddress(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "treasuryAddress") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// TreasuryAddress is a free data retrieval call binding the contract method 0xc5f956af. -// -// Solidity: function treasuryAddress() view returns(address) -func (_Contract *ContractSession) TreasuryAddress() (common.Address, error) { - return _Contract.Contract.TreasuryAddress(&_Contract.CallOpts) -} - -// TreasuryAddress is a free data retrieval call binding the contract method 0xc5f956af. -// -// Solidity: function treasuryAddress() view returns(address) -func (_Contract *ContractCallerSession) TreasuryAddress() (common.Address, error) { - return _Contract.Contract.TreasuryAddress(&_Contract.CallOpts) -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() pure returns(bytes3) -func (_Contract *ContractCaller) Version(opts *bind.CallOpts) ([3]byte, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "version") - - if err != nil { - return *new([3]byte), err - } - - out0 := *abi.ConvertType(out[0], new([3]byte)).(*[3]byte) - - return out0, err - -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() pure returns(bytes3) -func (_Contract *ContractSession) Version() ([3]byte, error) { - return _Contract.Contract.Version(&_Contract.CallOpts) -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() pure returns(bytes3) -func (_Contract *ContractCallerSession) Version() ([3]byte, error) { - return _Contract.Contract.Version(&_Contract.CallOpts) -} - -// VoteBookAddress is a free data retrieval call binding the contract method 0x893675c6. -// -// Solidity: function voteBookAddress() view returns(address) -func (_Contract *ContractCaller) VoteBookAddress(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "voteBookAddress") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// VoteBookAddress is a free data retrieval call binding the contract method 0x893675c6. -// -// Solidity: function voteBookAddress() view returns(address) -func (_Contract *ContractSession) VoteBookAddress() (common.Address, error) { - return _Contract.Contract.VoteBookAddress(&_Contract.CallOpts) -} - -// VoteBookAddress is a free data retrieval call binding the contract method 0x893675c6. -// -// Solidity: function voteBookAddress() view returns(address) -func (_Contract *ContractCallerSession) VoteBookAddress() (common.Address, error) { - return _Contract.Contract.VoteBookAddress(&_Contract.CallOpts) -} - -// SyncValidator is a paid mutator transaction binding the contract method 0xcc8343aa. -// -// Solidity: function _syncValidator(uint256 validatorID, bool syncPubkey) returns() -func (_Contract *ContractTransactor) SyncValidator(opts *bind.TransactOpts, validatorID *big.Int, syncPubkey bool) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "_syncValidator", validatorID, syncPubkey) -} - -// SyncValidator is a paid mutator transaction binding the contract method 0xcc8343aa. -// -// Solidity: function _syncValidator(uint256 validatorID, bool syncPubkey) returns() -func (_Contract *ContractSession) SyncValidator(validatorID *big.Int, syncPubkey bool) (*types.Transaction, error) { - return _Contract.Contract.SyncValidator(&_Contract.TransactOpts, validatorID, syncPubkey) -} - -// SyncValidator is a paid mutator transaction binding the contract method 0xcc8343aa. -// -// Solidity: function _syncValidator(uint256 validatorID, bool syncPubkey) returns() -func (_Contract *ContractTransactorSession) SyncValidator(validatorID *big.Int, syncPubkey bool) (*types.Transaction, error) { - return _Contract.Contract.SyncValidator(&_Contract.TransactOpts, validatorID, syncPubkey) -} - -// Initialize is a paid mutator transaction binding the contract method 0x10e51e14. -// -// Solidity: function initialize(uint256 sealedEpoch, uint256 _totalSupply, address nodeDriver, address lib, address _c, address owner) returns() -func (_Contract *ContractTransactor) Initialize(opts *bind.TransactOpts, sealedEpoch *big.Int, _totalSupply *big.Int, nodeDriver common.Address, lib common.Address, _c common.Address, owner common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "initialize", sealedEpoch, _totalSupply, nodeDriver, lib, _c, owner) -} - -// Initialize is a paid mutator transaction binding the contract method 0x10e51e14. -// -// Solidity: function initialize(uint256 sealedEpoch, uint256 _totalSupply, address nodeDriver, address lib, address _c, address owner) returns() -func (_Contract *ContractSession) Initialize(sealedEpoch *big.Int, _totalSupply *big.Int, nodeDriver common.Address, lib common.Address, _c common.Address, owner common.Address) (*types.Transaction, error) { - return _Contract.Contract.Initialize(&_Contract.TransactOpts, sealedEpoch, _totalSupply, nodeDriver, lib, _c, owner) -} - -// Initialize is a paid mutator transaction binding the contract method 0x10e51e14. -// -// Solidity: function initialize(uint256 sealedEpoch, uint256 _totalSupply, address nodeDriver, address lib, address _c, address owner) returns() -func (_Contract *ContractTransactorSession) Initialize(sealedEpoch *big.Int, _totalSupply *big.Int, nodeDriver common.Address, lib common.Address, _c common.Address, owner common.Address) (*types.Transaction, error) { - return _Contract.Contract.Initialize(&_Contract.TransactOpts, sealedEpoch, _totalSupply, nodeDriver, lib, _c, owner) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Contract *ContractTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Contract *ContractSession) RenounceOwnership() (*types.Transaction, error) { - return _Contract.Contract.RenounceOwnership(&_Contract.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Contract *ContractTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _Contract.Contract.RenounceOwnership(&_Contract.TransactOpts) -} - -// SealEpoch is a paid mutator transaction binding the contract method 0x592fe0c0. -// -// Solidity: function sealEpoch(uint256[] offlineTime, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee, uint256 epochGas) returns() -func (_Contract *ContractTransactor) SealEpoch(opts *bind.TransactOpts, offlineTime []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int, epochGas *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "sealEpoch", offlineTime, offlineBlocks, uptimes, originatedTxsFee, epochGas) -} - -// SealEpoch is a paid mutator transaction binding the contract method 0x592fe0c0. -// -// Solidity: function sealEpoch(uint256[] offlineTime, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee, uint256 epochGas) returns() -func (_Contract *ContractSession) SealEpoch(offlineTime []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int, epochGas *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpoch(&_Contract.TransactOpts, offlineTime, offlineBlocks, uptimes, originatedTxsFee, epochGas) -} - -// SealEpoch is a paid mutator transaction binding the contract method 0x592fe0c0. -// -// Solidity: function sealEpoch(uint256[] offlineTime, uint256[] offlineBlocks, uint256[] uptimes, uint256[] originatedTxsFee, uint256 epochGas) returns() -func (_Contract *ContractTransactorSession) SealEpoch(offlineTime []*big.Int, offlineBlocks []*big.Int, uptimes []*big.Int, originatedTxsFee []*big.Int, epochGas *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpoch(&_Contract.TransactOpts, offlineTime, offlineBlocks, uptimes, originatedTxsFee, epochGas) -} - -// SealEpochValidators is a paid mutator transaction binding the contract method 0xe08d7e66. -// -// Solidity: function sealEpochValidators(uint256[] nextValidatorIDs) returns() -func (_Contract *ContractTransactor) SealEpochValidators(opts *bind.TransactOpts, nextValidatorIDs []*big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "sealEpochValidators", nextValidatorIDs) -} - -// SealEpochValidators is a paid mutator transaction binding the contract method 0xe08d7e66. -// -// Solidity: function sealEpochValidators(uint256[] nextValidatorIDs) returns() -func (_Contract *ContractSession) SealEpochValidators(nextValidatorIDs []*big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpochValidators(&_Contract.TransactOpts, nextValidatorIDs) -} - -// SealEpochValidators is a paid mutator transaction binding the contract method 0xe08d7e66. -// -// Solidity: function sealEpochValidators(uint256[] nextValidatorIDs) returns() -func (_Contract *ContractTransactorSession) SealEpochValidators(nextValidatorIDs []*big.Int) (*types.Transaction, error) { - return _Contract.Contract.SealEpochValidators(&_Contract.TransactOpts, nextValidatorIDs) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Contract *ContractTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferOwnership", newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Contract *ContractSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Contract.Contract.TransferOwnership(&_Contract.TransactOpts, newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Contract *ContractTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Contract.Contract.TransferOwnership(&_Contract.TransactOpts, newOwner) -} - -// UpdateConstsAddress is a paid mutator transaction binding the contract method 0x860c2750. -// -// Solidity: function updateConstsAddress(address v) returns() -func (_Contract *ContractTransactor) UpdateConstsAddress(opts *bind.TransactOpts, v common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateConstsAddress", v) -} - -// UpdateConstsAddress is a paid mutator transaction binding the contract method 0x860c2750. -// -// Solidity: function updateConstsAddress(address v) returns() -func (_Contract *ContractSession) UpdateConstsAddress(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateConstsAddress(&_Contract.TransactOpts, v) -} - -// UpdateConstsAddress is a paid mutator transaction binding the contract method 0x860c2750. -// -// Solidity: function updateConstsAddress(address v) returns() -func (_Contract *ContractTransactorSession) UpdateConstsAddress(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateConstsAddress(&_Contract.TransactOpts, v) -} - -// UpdateLibAddress is a paid mutator transaction binding the contract method 0xe6f45adf. -// -// Solidity: function updateLibAddress(address v) returns() -func (_Contract *ContractTransactor) UpdateLibAddress(opts *bind.TransactOpts, v common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateLibAddress", v) -} - -// UpdateLibAddress is a paid mutator transaction binding the contract method 0xe6f45adf. -// -// Solidity: function updateLibAddress(address v) returns() -func (_Contract *ContractSession) UpdateLibAddress(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateLibAddress(&_Contract.TransactOpts, v) -} - -// UpdateLibAddress is a paid mutator transaction binding the contract method 0xe6f45adf. -// -// Solidity: function updateLibAddress(address v) returns() -func (_Contract *ContractTransactorSession) UpdateLibAddress(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateLibAddress(&_Contract.TransactOpts, v) -} - -// UpdateStakeTokenizerAddress is a paid mutator transaction binding the contract method 0xa2f6e6bc. -// -// Solidity: function updateStakeTokenizerAddress(address addr) returns() -func (_Contract *ContractTransactor) UpdateStakeTokenizerAddress(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateStakeTokenizerAddress", addr) -} - -// UpdateStakeTokenizerAddress is a paid mutator transaction binding the contract method 0xa2f6e6bc. -// -// Solidity: function updateStakeTokenizerAddress(address addr) returns() -func (_Contract *ContractSession) UpdateStakeTokenizerAddress(addr common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateStakeTokenizerAddress(&_Contract.TransactOpts, addr) -} - -// UpdateStakeTokenizerAddress is a paid mutator transaction binding the contract method 0xa2f6e6bc. -// -// Solidity: function updateStakeTokenizerAddress(address addr) returns() -func (_Contract *ContractTransactorSession) UpdateStakeTokenizerAddress(addr common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateStakeTokenizerAddress(&_Contract.TransactOpts, addr) -} - -// UpdateTreasuryAddress is a paid mutator transaction binding the contract method 0x841e4561. -// -// Solidity: function updateTreasuryAddress(address v) returns() -func (_Contract *ContractTransactor) UpdateTreasuryAddress(opts *bind.TransactOpts, v common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateTreasuryAddress", v) -} - -// UpdateTreasuryAddress is a paid mutator transaction binding the contract method 0x841e4561. -// -// Solidity: function updateTreasuryAddress(address v) returns() -func (_Contract *ContractSession) UpdateTreasuryAddress(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateTreasuryAddress(&_Contract.TransactOpts, v) -} - -// UpdateTreasuryAddress is a paid mutator transaction binding the contract method 0x841e4561. -// -// Solidity: function updateTreasuryAddress(address v) returns() -func (_Contract *ContractTransactorSession) UpdateTreasuryAddress(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateTreasuryAddress(&_Contract.TransactOpts, v) -} - -// UpdateVoteBookAddress is a paid mutator transaction binding the contract method 0x550359a0. -// -// Solidity: function updateVoteBookAddress(address v) returns() -func (_Contract *ContractTransactor) UpdateVoteBookAddress(opts *bind.TransactOpts, v common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateVoteBookAddress", v) -} - -// UpdateVoteBookAddress is a paid mutator transaction binding the contract method 0x550359a0. -// -// Solidity: function updateVoteBookAddress(address v) returns() -func (_Contract *ContractSession) UpdateVoteBookAddress(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateVoteBookAddress(&_Contract.TransactOpts, v) -} - -// UpdateVoteBookAddress is a paid mutator transaction binding the contract method 0x550359a0. -// -// Solidity: function updateVoteBookAddress(address v) returns() -func (_Contract *ContractTransactorSession) UpdateVoteBookAddress(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateVoteBookAddress(&_Contract.TransactOpts, v) -} - -// Fallback is a paid mutator transaction binding the contract fallback function. -// -// Solidity: fallback() payable returns() -func (_Contract *ContractTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { - return _Contract.contract.RawTransact(opts, calldata) -} - -// Fallback is a paid mutator transaction binding the contract fallback function. -// -// Solidity: fallback() payable returns() -func (_Contract *ContractSession) Fallback(calldata []byte) (*types.Transaction, error) { - return _Contract.Contract.Fallback(&_Contract.TransactOpts, calldata) -} - -// Fallback is a paid mutator transaction binding the contract fallback function. -// -// Solidity: fallback() payable returns() -func (_Contract *ContractTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { - return _Contract.Contract.Fallback(&_Contract.TransactOpts, calldata) -} - -// ContractChangedValidatorStatusIterator is returned from FilterChangedValidatorStatus and is used to iterate over the raw logs and unpacked data for ChangedValidatorStatus events raised by the Contract contract. -type ContractChangedValidatorStatusIterator struct { - Event *ContractChangedValidatorStatus // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractChangedValidatorStatusIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractChangedValidatorStatus) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractChangedValidatorStatus) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractChangedValidatorStatusIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractChangedValidatorStatusIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractChangedValidatorStatus represents a ChangedValidatorStatus event raised by the Contract contract. -type ContractChangedValidatorStatus struct { - ValidatorID *big.Int - Status *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterChangedValidatorStatus is a free log retrieval operation binding the contract event 0xcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e. -// -// Solidity: event ChangedValidatorStatus(uint256 indexed validatorID, uint256 status) -func (_Contract *ContractFilterer) FilterChangedValidatorStatus(opts *bind.FilterOpts, validatorID []*big.Int) (*ContractChangedValidatorStatusIterator, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "ChangedValidatorStatus", validatorIDRule) - if err != nil { - return nil, err - } - return &ContractChangedValidatorStatusIterator{contract: _Contract.contract, event: "ChangedValidatorStatus", logs: logs, sub: sub}, nil -} - -// WatchChangedValidatorStatus is a free log subscription operation binding the contract event 0xcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e. -// -// Solidity: event ChangedValidatorStatus(uint256 indexed validatorID, uint256 status) -func (_Contract *ContractFilterer) WatchChangedValidatorStatus(opts *bind.WatchOpts, sink chan<- *ContractChangedValidatorStatus, validatorID []*big.Int) (event.Subscription, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "ChangedValidatorStatus", validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractChangedValidatorStatus) - if err := _Contract.contract.UnpackLog(event, "ChangedValidatorStatus", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseChangedValidatorStatus is a log parse operation binding the contract event 0xcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e. -// -// Solidity: event ChangedValidatorStatus(uint256 indexed validatorID, uint256 status) -func (_Contract *ContractFilterer) ParseChangedValidatorStatus(log types.Log) (*ContractChangedValidatorStatus, error) { - event := new(ContractChangedValidatorStatus) - if err := _Contract.contract.UnpackLog(event, "ChangedValidatorStatus", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractDeactivatedValidatorIterator is returned from FilterDeactivatedValidator and is used to iterate over the raw logs and unpacked data for DeactivatedValidator events raised by the Contract contract. -type ContractDeactivatedValidatorIterator struct { - Event *ContractDeactivatedValidator // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractDeactivatedValidatorIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractDeactivatedValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractDeactivatedValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractDeactivatedValidatorIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractDeactivatedValidatorIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractDeactivatedValidator represents a DeactivatedValidator event raised by the Contract contract. -type ContractDeactivatedValidator struct { - ValidatorID *big.Int - DeactivatedEpoch *big.Int - DeactivatedTime *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDeactivatedValidator is a free log retrieval operation binding the contract event 0xac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e47. -// -// Solidity: event DeactivatedValidator(uint256 indexed validatorID, uint256 deactivatedEpoch, uint256 deactivatedTime) -func (_Contract *ContractFilterer) FilterDeactivatedValidator(opts *bind.FilterOpts, validatorID []*big.Int) (*ContractDeactivatedValidatorIterator, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "DeactivatedValidator", validatorIDRule) - if err != nil { - return nil, err - } - return &ContractDeactivatedValidatorIterator{contract: _Contract.contract, event: "DeactivatedValidator", logs: logs, sub: sub}, nil -} - -// WatchDeactivatedValidator is a free log subscription operation binding the contract event 0xac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e47. -// -// Solidity: event DeactivatedValidator(uint256 indexed validatorID, uint256 deactivatedEpoch, uint256 deactivatedTime) -func (_Contract *ContractFilterer) WatchDeactivatedValidator(opts *bind.WatchOpts, sink chan<- *ContractDeactivatedValidator, validatorID []*big.Int) (event.Subscription, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "DeactivatedValidator", validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractDeactivatedValidator) - if err := _Contract.contract.UnpackLog(event, "DeactivatedValidator", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseDeactivatedValidator is a log parse operation binding the contract event 0xac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e47. -// -// Solidity: event DeactivatedValidator(uint256 indexed validatorID, uint256 deactivatedEpoch, uint256 deactivatedTime) -func (_Contract *ContractFilterer) ParseDeactivatedValidator(log types.Log) (*ContractDeactivatedValidator, error) { - event := new(ContractDeactivatedValidator) - if err := _Contract.contract.UnpackLog(event, "DeactivatedValidator", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Contract contract. -type ContractOwnershipTransferredIterator struct { - Event *ContractOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractOwnershipTransferredIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractOwnershipTransferred represents a OwnershipTransferred event raised by the Contract contract. -type ContractOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Contract *ContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ContractOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return &ContractOwnershipTransferredIterator{contract: _Contract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Contract *ContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ContractOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractOwnershipTransferred) - if err := _Contract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Contract *ContractFilterer) ParseOwnershipTransferred(log types.Log) (*ContractOwnershipTransferred, error) { - event := new(ContractOwnershipTransferred) - if err := _Contract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUpdatedBaseRewardPerSecIterator is returned from FilterUpdatedBaseRewardPerSec and is used to iterate over the raw logs and unpacked data for UpdatedBaseRewardPerSec events raised by the Contract contract. -type ContractUpdatedBaseRewardPerSecIterator struct { - Event *ContractUpdatedBaseRewardPerSec // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUpdatedBaseRewardPerSecIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUpdatedBaseRewardPerSec) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUpdatedBaseRewardPerSec) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUpdatedBaseRewardPerSecIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUpdatedBaseRewardPerSecIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUpdatedBaseRewardPerSec represents a UpdatedBaseRewardPerSec event raised by the Contract contract. -type ContractUpdatedBaseRewardPerSec struct { - Value *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdatedBaseRewardPerSec is a free log retrieval operation binding the contract event 0x8cd9dae1bbea2bc8a5e80ffce2c224727a25925130a03ae100619a8861ae2396. -// -// Solidity: event UpdatedBaseRewardPerSec(uint256 value) -func (_Contract *ContractFilterer) FilterUpdatedBaseRewardPerSec(opts *bind.FilterOpts) (*ContractUpdatedBaseRewardPerSecIterator, error) { - - logs, sub, err := _Contract.contract.FilterLogs(opts, "UpdatedBaseRewardPerSec") - if err != nil { - return nil, err - } - return &ContractUpdatedBaseRewardPerSecIterator{contract: _Contract.contract, event: "UpdatedBaseRewardPerSec", logs: logs, sub: sub}, nil -} - -// WatchUpdatedBaseRewardPerSec is a free log subscription operation binding the contract event 0x8cd9dae1bbea2bc8a5e80ffce2c224727a25925130a03ae100619a8861ae2396. -// -// Solidity: event UpdatedBaseRewardPerSec(uint256 value) -func (_Contract *ContractFilterer) WatchUpdatedBaseRewardPerSec(opts *bind.WatchOpts, sink chan<- *ContractUpdatedBaseRewardPerSec) (event.Subscription, error) { - - logs, sub, err := _Contract.contract.WatchLogs(opts, "UpdatedBaseRewardPerSec") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUpdatedBaseRewardPerSec) - if err := _Contract.contract.UnpackLog(event, "UpdatedBaseRewardPerSec", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdatedBaseRewardPerSec is a log parse operation binding the contract event 0x8cd9dae1bbea2bc8a5e80ffce2c224727a25925130a03ae100619a8861ae2396. -// -// Solidity: event UpdatedBaseRewardPerSec(uint256 value) -func (_Contract *ContractFilterer) ParseUpdatedBaseRewardPerSec(log types.Log) (*ContractUpdatedBaseRewardPerSec, error) { - event := new(ContractUpdatedBaseRewardPerSec) - if err := _Contract.contract.UnpackLog(event, "UpdatedBaseRewardPerSec", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUpdatedOfflinePenaltyThresholdIterator is returned from FilterUpdatedOfflinePenaltyThreshold and is used to iterate over the raw logs and unpacked data for UpdatedOfflinePenaltyThreshold events raised by the Contract contract. -type ContractUpdatedOfflinePenaltyThresholdIterator struct { - Event *ContractUpdatedOfflinePenaltyThreshold // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUpdatedOfflinePenaltyThresholdIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUpdatedOfflinePenaltyThreshold) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUpdatedOfflinePenaltyThreshold) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUpdatedOfflinePenaltyThresholdIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUpdatedOfflinePenaltyThresholdIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUpdatedOfflinePenaltyThreshold represents a UpdatedOfflinePenaltyThreshold event raised by the Contract contract. -type ContractUpdatedOfflinePenaltyThreshold struct { - BlocksNum *big.Int - Period *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdatedOfflinePenaltyThreshold is a free log retrieval operation binding the contract event 0x702756a07c05d0bbfd06fc17b67951a5f4deb7bb6b088407e68a58969daf2a34. -// -// Solidity: event UpdatedOfflinePenaltyThreshold(uint256 blocksNum, uint256 period) -func (_Contract *ContractFilterer) FilterUpdatedOfflinePenaltyThreshold(opts *bind.FilterOpts) (*ContractUpdatedOfflinePenaltyThresholdIterator, error) { - - logs, sub, err := _Contract.contract.FilterLogs(opts, "UpdatedOfflinePenaltyThreshold") - if err != nil { - return nil, err - } - return &ContractUpdatedOfflinePenaltyThresholdIterator{contract: _Contract.contract, event: "UpdatedOfflinePenaltyThreshold", logs: logs, sub: sub}, nil -} - -// WatchUpdatedOfflinePenaltyThreshold is a free log subscription operation binding the contract event 0x702756a07c05d0bbfd06fc17b67951a5f4deb7bb6b088407e68a58969daf2a34. -// -// Solidity: event UpdatedOfflinePenaltyThreshold(uint256 blocksNum, uint256 period) -func (_Contract *ContractFilterer) WatchUpdatedOfflinePenaltyThreshold(opts *bind.WatchOpts, sink chan<- *ContractUpdatedOfflinePenaltyThreshold) (event.Subscription, error) { - - logs, sub, err := _Contract.contract.WatchLogs(opts, "UpdatedOfflinePenaltyThreshold") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUpdatedOfflinePenaltyThreshold) - if err := _Contract.contract.UnpackLog(event, "UpdatedOfflinePenaltyThreshold", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdatedOfflinePenaltyThreshold is a log parse operation binding the contract event 0x702756a07c05d0bbfd06fc17b67951a5f4deb7bb6b088407e68a58969daf2a34. -// -// Solidity: event UpdatedOfflinePenaltyThreshold(uint256 blocksNum, uint256 period) -func (_Contract *ContractFilterer) ParseUpdatedOfflinePenaltyThreshold(log types.Log) (*ContractUpdatedOfflinePenaltyThreshold, error) { - event := new(ContractUpdatedOfflinePenaltyThreshold) - if err := _Contract.contract.UnpackLog(event, "UpdatedOfflinePenaltyThreshold", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -var ContractBinRuntime = "0x6080604052600436106102855760003560e01c80638b0e9f3f11610153578063c65ee0e1116100cb578063d46fa5181161007f578063e08d7e6611610064578063e08d7e6614610b1f578063e6f45adf14610b9c578063f2fde38b14610bcf57610285565b8063d46fa51814610af5578063d96ed50514610b0a57610285565b8063cc8343aa116100b0578063cc8343aa14610a51578063cfd4766314610a83578063cfdbb7cd14610abc57610285565b8063c65ee0e114610a12578063c7be95de14610a3c57610285565b8063a2f6e6bc11610122578063b5d8962711610107578063b5d8962714610959578063b810e411146109c4578063c5f956af146109fd57610285565b8063a2f6e6bc146108ed578063a86a056f1461092057610285565b80638b0e9f3f1461083b5780638da5cb5b146108505780638f32d59b1461086557806396c7ee461461088e57610285565b8063592fe0c0116102015780637cacb1d6116101b5578063854873e11161019a578063854873e114610754578063860c2750146107f3578063893675c61461082657610285565b80637cacb1d61461070c578063841e45611461072157610285565b8063670322f8116101e6578063670322f8146106a9578063715018a6146106e257806376671808146106f757610285565b8063592fe0c0146105215780635fab23a81461069457610285565b80631f2701521161025857806339b80c001161023d57806339b80c001461044257806354fd4d50146104a4578063550359a0146104ee57610285565b80631f270152146103d057806328f731481461042d57610285565b80630135b1db146102ee5780630e559d821461033357806310e51e141461036457806318160ddd146103bb575b366102d7576040805162461bcd60e51b815260206004820152601560248201527f7472616e7366657273206e6f7420616c6c6f7765640000000000000000000000604482015290519081900360640190fd5b6080546102ec906001600160a01b0316610c02565b005b3480156102fa57600080fd5b506103216004803603602081101561031157600080fd5b50356001600160a01b0316610c2b565b60408051918252519081900360200190f35b34801561033f57600080fd5b50610348610c3d565b604080516001600160a01b039092168252519081900360200190f35b34801561037057600080fd5b506102ec600480360360c081101561038757600080fd5b508035906020810135906001600160a01b0360408201358116916060810135821691608082013581169160a0013516610c4c565b3480156103c757600080fd5b50610321610e50565b3480156103dc57600080fd5b5061040f600480360360608110156103f357600080fd5b506001600160a01b038135169060208101359060400135610e56565b60408051938452602084019290925282820152519081900360600190f35b34801561043957600080fd5b50610321610e88565b34801561044e57600080fd5b5061046c6004803603602081101561046557600080fd5b5035610e8e565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b3480156104b057600080fd5b506104b9610ed0565b604080517fffffff00000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b3480156104fa57600080fd5b506102ec6004803603602081101561051157600080fd5b50356001600160a01b0316610ef5565b34801561052d57600080fd5b506102ec600480360360a081101561054457600080fd5b81019060208101813564010000000081111561055f57600080fd5b82018360208201111561057157600080fd5b8035906020019184602083028401116401000000008311171561059357600080fd5b9193909290916020810190356401000000008111156105b157600080fd5b8201836020820111156105c357600080fd5b803590602001918460208302840111640100000000831117156105e557600080fd5b91939092909160208101903564010000000081111561060357600080fd5b82018360208201111561061557600080fd5b8035906020019184602083028401116401000000008311171561063757600080fd5b91939092909160208101903564010000000081111561065557600080fd5b82018360208201111561066757600080fd5b8035906020019184602083028401116401000000008311171561068957600080fd5b919350915035610f88565b3480156106a057600080fd5b50610321611243565b3480156106b557600080fd5b50610321600480360360408110156106cc57600080fd5b506001600160a01b038135169060200135611249565b3480156106ee57600080fd5b506102ec61128d565b34801561070357600080fd5b50610321611348565b34801561071857600080fd5b50610321611351565b34801561072d57600080fd5b506102ec6004803603602081101561074457600080fd5b50356001600160a01b0316611357565b34801561076057600080fd5b5061077e6004803603602081101561077757600080fd5b50356113ea565b6040805160208082528351818301528351919283929083019185019080838360005b838110156107b85781810151838201526020016107a0565b50505050905090810190601f1680156107e55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156107ff57600080fd5b506102ec6004803603602081101561081657600080fd5b50356001600160a01b03166114a3565b34801561083257600080fd5b50610348611536565b34801561084757600080fd5b50610321611545565b34801561085c57600080fd5b5061034861154b565b34801561087157600080fd5b5061087a61155a565b604080519115158252519081900360200190f35b34801561089a57600080fd5b506108c7600480360360408110156108b157600080fd5b506001600160a01b03813516906020013561156b565b604080519485526020850193909352838301919091526060830152519081900360800190f35b3480156108f957600080fd5b506102ec6004803603602081101561091057600080fd5b50356001600160a01b031661159d565b34801561092c57600080fd5b506103216004803603604081101561094357600080fd5b506001600160a01b038135169060200135611630565b34801561096557600080fd5b506109836004803603602081101561097c57600080fd5b503561164d565b604080519788526020880196909652868601949094526060860192909252608085015260a08401526001600160a01b031660c0830152519081900360e00190f35b3480156109d057600080fd5b5061040f600480360360408110156109e757600080fd5b506001600160a01b038135169060200135611693565b348015610a0957600080fd5b506103486116bf565b348015610a1e57600080fd5b5061032160048036036020811015610a3557600080fd5b50356116ce565b348015610a4857600080fd5b506103216116e0565b348015610a5d57600080fd5b506102ec60048036036040811015610a7457600080fd5b508035906020013515156116e6565b348015610a8f57600080fd5b5061032160048036036040811015610aa657600080fd5b506001600160a01b038135169060200135611915565b348015610ac857600080fd5b5061087a60048036036040811015610adf57600080fd5b506001600160a01b038135169060200135611932565b348015610b0157600080fd5b506103486119c9565b348015610b1657600080fd5b506103216119d8565b348015610b2b57600080fd5b506102ec60048036036020811015610b4257600080fd5b810190602081018135640100000000811115610b5d57600080fd5b820183602082011115610b6f57600080fd5b80359060200191846020830284011164010000000083111715610b9157600080fd5b5090925090506119de565b348015610ba857600080fd5b506102ec60048036036020811015610bbf57600080fd5b50356001600160a01b0316611b22565b348015610bdb57600080fd5b506102ec60048036036020811015610bf257600080fd5b50356001600160a01b0316611bb5565b3660008037600080366000845af43d6000803e808015610c21573d6000f35b3d6000fd5b505050565b60696020526000908152604090205481565b607b546001600160a01b031681565b600054610100900460ff1680610c655750610c65611c1a565b80610c73575060005460ff16155b610cae5760405162461bcd60e51b815260040180806020018281038252602e815260200180613441602e913960400191505060405180910390fd5b600054610100900460ff16158015610d1457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b610d1d82611c20565b6067879055606680546001600160a01b038088167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556080805487841690831617905560818054868416921691909117908190556076889055604080517f38eca546000000000000000000000000000000000000000000000000000000008152905191909216916338eca546916004808301926020929190829003018186803b158015610dcf57600080fd5b505afa158015610de3573d6000803e3d6000fd5b505050506040513d6020811015610df957600080fd5b5051607e55610e06611d82565b6000888152607760205260409020600701558015610e4757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050505050565b60765481565b607160209081526000938452604080852082529284528284209052825290208054600182015460029092015490919083565b606d5481565b607760205280600052604060002060009150905080600701549080600801549080600901549080600a01549080600b01549080600c01549080600d0154905087565b7f33303400000000000000000000000000000000000000000000000000000000005b90565b610efd61155a565b610f4e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b608280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b610f9133611d86565b610fcc5760405162461bcd60e51b81526004018080602001828103825260298152602001806133f76029913960400191505060405180910390fd5b600060776000610fda611348565b8152602001908152602001600020905060608160060180548060200260200160405190810160405280929190818152602001828054801561103a57602002820191906000526020600020905b815481526020019060010190808311611026575b505050505090506110c182828d8d80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508c8c80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d9d92505050565b606754600090815260776020526040902060078101546001906110e2611d82565b11156110f95781600701546110f5611d82565b0390505b61117b818584868d8d80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508c8c80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611fa492505050565b611185818661278e565b505061118f611348565b60675561119a611d82565b6007830155608154604080517fd9a7c1f900000000000000000000000000000000000000000000000000000000815290516001600160a01b039092169163d9a7c1f991600480820192602092909190829003018186803b1580156111fd57600080fd5b505afa158015611211573d6000803e3d6000fd5b505050506040513d602081101561122757600080fd5b5051600b83015550607654600d90910155505050505050505050565b606e5481565b60006112558383611932565b61126157506000611287565b506001600160a01b03821660009081526073602090815260408083208484529091529020545b92915050565b61129561155a565b6112e6576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b60675460010190565b60675481565b61135f61155a565b6113b0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b607f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b606a6020908152600091825260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001861615020190931692909204918201849004840281018401909452808452909183018282801561149b5780601f106114705761010080835404028352916020019161149b565b820191906000526020600020905b81548152906001019060200180831161147e57829003601f168201915b505050505081565b6114ab61155a565b6114fc576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b608180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6082546001600160a01b031681565b606c5481565b6033546001600160a01b031690565b6033546001600160a01b0316331490565b607360209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b6115a561155a565b6115f6576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b607b80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b607060209081526000928352604080842090915290825290205481565b606860205260009081526040902080546001820154600283015460038401546004850154600586015460069096015494959394929391929091906001600160a01b031687565b607460209081526000928352604080842090915290825290208054600182015460029092015490919083565b607f546001600160a01b031681565b607a6020526000908152604090205481565b606b5481565b6116ef82612981565b611740576040805162461bcd60e51b815260206004820152601760248201527f76616c696461746f7220646f65736e2774206578697374000000000000000000604482015290519081900360640190fd5b6000828152606860205260409020600381015490541561175e575060005b606654604080517fa4066fbe000000000000000000000000000000000000000000000000000000008152600481018690526024810184905290516001600160a01b039092169163a4066fbe9160448082019260009290919082900301818387803b1580156117cb57600080fd5b505af11580156117df573d6000803e3d6000fd5b505050508180156117ef57508015155b15610c26576066546000848152606a60205260409081902081517f242a6e3f0000000000000000000000000000000000000000000000000000000081526004810187815260248201938452825460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001831615610100020190911604604483018190526001600160a01b039095169463242a6e3f948994939091606490910190849080156118e05780601f106118b5576101008083540402835291602001916118e0565b820191906000526020600020905b8154815290600101906020018083116118c357829003601f168201915b50509350505050600060405180830381600087803b15801561190157600080fd5b505af1158015610e47573d6000803e3d6000fd5b607260209081526000928352604080842090915290825290205481565b6001600160a01b03821660009081526073602090815260408083208484529091528120600201541580159061198957506001600160a01b038316600090815260736020908152604080832085845290915290205415155b80156119c257506001600160a01b03831660009081526073602090815260408083208584529091529020600201546119bf611d82565b11155b9392505050565b6081546001600160a01b031690565b607e5481565b6119e733611d86565b611a225760405162461bcd60e51b81526004018080602001828103825260298152602001806133f76029913960400191505060405180910390fd5b600060776000611a30611348565b8152602001908152602001600020905060008090505b82811015611aa9576000848483818110611a5c57fe5b60209081029290920135600081815260688452604080822060030154948890529020839055600c860154909350611a9a91508263ffffffff61299816565b600c8501555050600101611a46565b50611ab860068201848461331f565b50606654607e54604080517f07aaf3440000000000000000000000000000000000000000000000000000000081526004810192909252516001600160a01b03909216916307aaf3449160248082019260009290919082900301818387803b15801561190157600080fd5b611b2a61155a565b611b7b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b608080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b611bbd61155a565b611c0e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b611c17816129f2565b50565b303b1590565b600054610100900460ff1680611c395750611c39611c1a565b80611c47575060005460ff16155b611c825760405162461bcd60e51b815260040180806020018281038252602e815260200180613441602e913960400191505060405180910390fd5b600054610100900460ff16158015611ce857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015611d7e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b4290565b6066546001600160a01b038281169116145b919050565b60005b8351811015611f9d57608160009054906101000a90046001600160a01b03166001600160a01b0316635a68f01a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611df757600080fd5b505afa158015611e0b573d6000803e3d6000fd5b505050506040513d6020811015611e2157600080fd5b50518251839083908110611e3157fe5b6020026020010151118015611ed35750608160009054906101000a90046001600160a01b03166001600160a01b031662cc7f836040518163ffffffff1660e01b815260040160206040518083038186803b158015611e8e57600080fd5b505afa158015611ea2573d6000803e3d6000fd5b505050506040513d6020811015611eb857600080fd5b50518351849083908110611ec857fe5b602002602001015110155b15611f1457611ef6848281518110611ee757fe5b60200260200101516008612aab565b611f14848281518110611f0557fe5b602002602001015160006116e6565b828181518110611f2057fe5b6020026020010151856004016000868481518110611f3a57fe5b6020026020010151815260200190815260200160002081905550818181518110611f6057fe5b6020026020010151856005016000868481518110611f7a57fe5b602090810291909101810151825281019190915260400160002055600101611da0565b5050505050565b611fac613366565b6040518060a001604052808551604051908082528060200260200182016040528015611fe2578160200160208202803883390190505b50815260200160008152602001855160405190808252806020026020018201604052801561201a578160200160208202803883390190505b508152602001600081526020016000815250905060008090505b845181101561213557600086600301600087848151811061205157fe5b6020026020010151815260200190815260200160002054905060008090508185848151811061207c57fe5b602002602001015111156120a3578185848151811061209757fe5b60200260200101510390505b898684815181106120b057fe5b60200260200101518202816120c157fe5b04846040015184815181106120d257fe5b60200260200101818152505061210c846040015184815181106120f157fe5b6020026020010151856060015161299890919063ffffffff16565b60608501526080840151612126908263ffffffff61299816565b60808501525050600101612034565b5060005b84518110156121fe578784828151811061214f57fe5b60200260200101518986848151811061216457fe5b60200260200101518a60000160008a878151811061217e57fe5b6020026020010151815260200190815260200160002054028161219d57fe5b0402816121a657fe5b04826000015182815181106121b757fe5b6020026020010181815250506121f1826000015182815181106121d657fe5b6020026020010151836020015161299890919063ffffffff16565b6020830152600101612139565b5060005b845181101561263d5760006122ab89608160009054906101000a90046001600160a01b03166001600160a01b031663d9a7c1f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561225f57600080fd5b505afa158015612273573d6000803e3d6000fd5b505050506040513d602081101561228957600080fd5b5051855180518690811061229957fe5b60200260200101518660200151612bd5565b90506122e76122da8460800151856040015185815181106122c857fe5b60200260200101518660600151612c24565b829063ffffffff61299816565b905060008683815181106122f757fe5b60209081029190910181015160008181526068835260408082206006015460815482517fa778651500000000000000000000000000000000000000000000000000000000815292519496506001600160a01b039182169593946123ad948994929093169263a77865159260048082019391829003018186803b15801561237c57600080fd5b505afa158015612390573d6000803e3d6000fd5b505050506040513d60208110156123a657600080fd5b5051612d8d565b6001600160a01b03831660009081526072602090815260408083208784529091529020549091508015612554576000816123e78587611249565b8402816123f057fe5b0490508083036123fe613395565b6001600160a01b03861660009081526073602090815260408083208a8452909152902060030154612430908490612daa565b905061243a613395565b612445836000612daa565b6001600160a01b0388166000908152606f602090815260408083208c8452825291829020825160608101845281548152600182015492810192909252600201549181019190915290915061249a908383612f6c565b6001600160a01b0388166000818152606f602090815260408083208d84528252808320855181558583015160018083019190915595820151600291820155938352607482528083208d845282529182902082516060810184528154815294810154918501919091529091015490820152612515908383612f6c565b6001600160a01b03881660009081526074602090815260408083208c845282529182902083518155908301516001820155910151600290910155505050505b6000848152606860205260408120600301548387039181156125865781612579612f87565b84028161258257fe5b0490505b808e600101600089815260200190815260200160002054018f6001016000898152602001908152602001600020819055508a89815181106125c357fe5b60200260200101518f6003016000898152602001908152602001600020819055508b89815181106125f057fe5b60200260200101518e600201600089815260200190815260200160002054018f60020160008981526020019081526020016000208190555050505050505050508080600101915050612202565b50608081015160088701819055602082015160098801556060820151600a880155607654111561267b57600886015460768054919091039055612681565b60006076555b607f546001600160a01b031615610e4757600061269c612f87565b608160009054906101000a90046001600160a01b03166001600160a01b03166394c3e9146040518163ffffffff1660e01b815260040160206040518083038186803b1580156126ea57600080fd5b505afa1580156126fe573d6000803e3d6000fd5b505050506040513d602081101561271457600080fd5b50516080840151028161272357fe5b04905061272f81612f93565b607f546040516001600160a01b03909116908290600081818185875af1925050503d806000811461277c576040519150601f19603f3d011682016040523d82523d6000602084013e612781565b606091505b5050505050505050505050565b608154604080517f3a3ef66c00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b031691633a3ef66c916004808301926020929190829003018186803b1580156127ec57600080fd5b505afa158015612800573d6000803e3d6000fd5b505050506040513d602081101561281657600080fd5b50518302600101905060008161282a612f87565b84028161283357fe5b0490506000608160009054906101000a90046001600160a01b03166001600160a01b0316632c8c36a56040518163ffffffff1660e01b815260040160206040518083038186803b15801561288657600080fd5b505afa15801561289a573d6000803e3d6000fd5b505050506040513d60208110156128b057600080fd5b505190508481016128bf612f87565b820283870201816128cc57fe5b0491506128d882613031565b915060006128e4612f87565b83607e5402816128f057fe5b04905061297681608160009054906101000a90046001600160a01b03166001600160a01b03166338eca5466040518163ffffffff1660e01b815260040160206040518083038186803b15801561294557600080fd5b505afa158015612959573d6000803e3d6000fd5b505050506040513d602081101561296f57600080fd5b505161309f565b607e55505050505050565b600090815260686020526040902060050154151590565b6000828201838110156119c2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038116612a375760405162461bcd60e51b81526004018080602001828103825260268152602001806133d16026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b600082815260686020526040902054158015612ac657508015155b15612af357600082815260686020526040902060030154606d54612aef9163ffffffff6130d416565b606d555b600082815260686020526040902054811115611d7e57600082815260686020526040902081815560020154612b9b57612b2a611348565b600083815260686020526040902060020155612b44611d82565b6000838152606860209081526040918290206001810184905560020154825190815290810192909252805184927fac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e4792908290030190a25b60408051828152905183917fcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e919081900360200190a25050565b600082612be457506000612c1c565b6000612bf6868663ffffffff61311616565b9050612c1883612c0c838763ffffffff61311616565b9063ffffffff61316f16565b9150505b949350505050565b600082612c33575060006119c2565b6000612c4983612c0c878763ffffffff61311616565b9050612d84612c56612f87565b608154604080517f94c3e9140000000000000000000000000000000000000000000000000000000081529051612c0c926001600160a01b0316916394c3e914916004808301926020929190829003018186803b158015612cb557600080fd5b505afa158015612cc9573d6000803e3d6000fd5b505050506040513d6020811015612cdf57600080fd5b5051608154604080517fc74dd62100000000000000000000000000000000000000000000000000000000815290516001600160a01b039092169163c74dd62191600480820192602092909190829003018186803b158015612d3f57600080fd5b505afa158015612d53573d6000803e3d6000fd5b505050506040513d6020811015612d6957600080fd5b5051612d73612f87565b03038461311690919063ffffffff16565b95945050505050565b60006119c2612d9a612f87565b612c0c858563ffffffff61311616565b612db2613395565b60405180606001604052806000815260200160008152602001600081525090506000608160009054906101000a90046001600160a01b03166001600160a01b0316635e2308d26040518163ffffffff1660e01b815260040160206040518083038186803b158015612e2257600080fd5b505afa158015612e36573d6000803e3d6000fd5b505050506040513d6020811015612e4c57600080fd5b505190508215612f4457600081612e61612f87565b0390506000612ef3608160009054906101000a90046001600160a01b03166001600160a01b0316630d4955e36040518163ffffffff1660e01b815260040160206040518083038186803b158015612eb757600080fd5b505afa158015612ecb573d6000803e3d6000fd5b505050506040513d6020811015612ee157600080fd5b5051612c0c848863ffffffff61311616565b90506000612f14612f02612f87565b612c0c8987860163ffffffff61311616565b9050612f31612f21612f87565b612c0c898763ffffffff61311616565b602086018190529003845250612f659050565b612f5f612f4f612f87565b612c0c868463ffffffff61311616565b60408301525b5092915050565b612f74613395565b612c1c612f8185856131b1565b836131b1565b670de0b6b3a764000090565b606654604080517f66e7ea0f0000000000000000000000000000000000000000000000000000000081523060048201526024810184905290516001600160a01b03909216916366e7ea0f9160448082019260009290919082900301818387803b158015612fff57600080fd5b505af1158015613013573d6000803e3d6000fd5b505060765461302b925090508263ffffffff61299816565b60765550565b6000606461303d612f87565b6069028161304757fe5b0482111561306b576064613059612f87565b6069028161306357fe5b049050611d98565b6064613075612f87565b605f028161307f57fe5b0482101561309b576064613091612f87565b605f028161306357fe5b5090565b600066038d7ea4c680008311156130be575066038d7ea4c68000611287565b818310156130cd575080611287565b5090919050565b60006119c283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613223565b60008261312557506000611287565b8282028284828161313257fe5b04146119c25760405162461bcd60e51b81526004018080602001828103825260218152602001806134206021913960400191505060405180910390fd5b60006119c283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506132ba565b6131b9613395565b60408051606081019091528251845182916131da919063ffffffff61299816565b81526020016131fa8460200151866020015161299890919063ffffffff16565b815260200161321a8460400151866040015161299890919063ffffffff16565b90529392505050565b600081848411156132b25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561327757818101518382015260200161325f565b50505050905090810190601f1680156132a45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836133095760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561327757818101518382015260200161325f565b50600083858161331557fe5b0495945050505050565b82805482825590600052602060002090810192821561335a579160200282015b8281111561335a57823582559160200191906001019061333f565b5061309b9291506133b6565b6040518060a0016040528060608152602001600081526020016060815260200160008152602001600081525090565b60405180606001604052806000815260200160008152602001600081525090565b610ef291905b8082111561309b57600081556001016133bc56fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737363616c6c6572206973206e6f7420746865204e6f64654472697665724175746820636f6e7472616374536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a265627a7a723158201ba2eb9163d4b98d4977fa009fb214c9d86da5cc8771883025ff4c7a2ea550d164736f6c63430005110032" diff --git a/evm/go-x1/gossip/contract/sfclib100/contract.go b/evm/go-x1/gossip/contract/sfclib100/contract.go deleted file mode 100644 index 3c485de..0000000 --- a/evm/go-x1/gossip/contract/sfclib100/contract.go +++ /dev/null @@ -1,4066 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package sfclib100 - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// ContractMetaData contains all meta data concerning the Contract contract. -var ContractMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"BurntFTM\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"}],\"name\":\"ChangedValidatorStatus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockupExtraReward\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockupBaseReward\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlockedReward\",\"type\":\"uint256\"}],\"name\":\"ClaimedRewards\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"auth\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"createdEpoch\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"createdTime\",\"type\":\"uint256\"}],\"name\":\"CreatedValidator\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deactivatedEpoch\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deactivatedTime\",\"type\":\"uint256\"}],\"name\":\"DeactivatedValidator\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Delegated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LockedUpStake\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"RefundedSlashedLegacyDelegation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockupExtraReward\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockupBaseReward\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlockedReward\",\"type\":\"uint256\"}],\"name\":\"RestakedRewards\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"wrID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Undelegated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"penalty\",\"type\":\"uint256\"}],\"name\":\"UnlockedStake\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"refundRatio\",\"type\":\"uint256\"}],\"name\":\"UpdatedSlashingRefundRatio\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"wrID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"syncPubkey\",\"type\":\"bool\"}],\"name\":\"_syncValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"currentEpoch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"currentSealedEpoch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getEpochSnapshot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"epochFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalBaseRewardWeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalTxRewardWeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseRewardPerSecond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"getLockedStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getLockupInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"lockedStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fromEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getStashedLockupRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"lockupExtraReward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupBaseReward\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlockedReward\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getValidator\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receivedStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdTime\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"auth\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"getValidatorID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getValidatorPubkey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getWithdrawalRequest\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"isLockedUp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"lastValidatorID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minGasPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"slashingRefundRatio\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"stakeTokenizerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"stashedRewardsUntilEpoch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalActiveStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSlashedStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"voteBookAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"}],\"name\":\"getEpochValidatorIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"}],\"name\":\"getEpochReceivedStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"}],\"name\":\"getEpochAccumulatedRewardPerToken\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"}],\"name\":\"getEpochAccumulatedUptime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"}],\"name\":\"getEpochAccumulatedOriginatedTxsFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"}],\"name\":\"getEpochOfflineTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"epoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"}],\"name\":\"getEpochOfflineBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"}],\"name\":\"rewardsStash\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"auth\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedTime\",\"type\":\"uint256\"}],\"name\":\"setGenesisValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockedStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupFromEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupEndTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyUnlockPenalty\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"}],\"name\":\"setGenesisDelegation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"}],\"name\":\"createValidator\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"}],\"name\":\"getSelfStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"delegate\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"validatorAuth\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gas\",\"type\":\"uint256\"}],\"name\":\"recountVotes\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"wrID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"undelegate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"liquidateSFTM\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"v\",\"type\":\"address\"}],\"name\":\"updateSFTMFinalizer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"}],\"name\":\"isSlashed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"wrID\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"}],\"name\":\"deactivateValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"pendingRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"stashRewards\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"claimRewards\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"restakeRewards\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFTM\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"}],\"name\":\"getUnlockedStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"lockStake\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"relockStake\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"unlockStake\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"refundRatio\",\"type\":\"uint256\"}],\"name\":\"updateSlashingRefundRatio\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50615220806100206000396000f3fe6080604052600436106103815760003560e01c8063854873e1116101d1578063b88a37e211610102578063cfd47663116100a0578063de67f2151161006f578063de67f21514610f3a578063df00c92214610f70578063e261641a14610fa0578063f2fde38b14610fd057610381565b8063cfd4766314610e83578063cfdbb7cd14610ebc578063d96ed50514610ef5578063dc31e1af14610f0a57610381565b8063c5f956af116100dc578063c5f956af14610dfd578063c65ee0e114610e12578063c7be95de14610e3c578063cc8343aa14610e5157610381565b8063b88a37e214610d23578063bd14d90714610d9d578063c3de580e14610dd357610381565b806396c7ee461161016f578063a5a470ad11610149578063a5a470ad14610bd6578063a86a056f14610c46578063b5d8962714610c7f578063b810e41114610cea57610381565b806396c7ee4614610b2a5780639fa6dd3514610b89578063a198d22914610ba657610381565b80638cddb015116101ab5780638cddb01514610a895780638da5cb5b14610ac25780638f32d59b14610ad757806390a6c47514610b0057610381565b8063854873e1146109c0578063893675c614610a5f5780638b0e9f3f14610a7457610381565b80633a488397116102b65780635fab23a8116102545780636f498663116102235780636f49866314610948578063715018a61461098157806376671808146109965780637cacb1d6146109ab57610381565b80635fab23a8146108915780636099ecb2146108a657806361e53fcc146108df578063670322f81461090f57610381565b80634f864df4116102905780634f864df4146107565780634feb92f31461078c5780635601fe011461083757806358f95b801461086157610381565b80633a488397146106b7578063441a3e70146106f65780634f7c4efb1461072657610381565b80631d3ac42c1161032357806320c0849d116102fd57806320c0849d146105c257806328f731481461060d5780632ce719601461062257806339b80c001461065557610381565b80631d3ac42c146105055780631e702f83146105355780631f2701521461056557610381565b80630e559d821161035f5780630e559d821461042157806312622d0e1461045257806318160ddd1461048b57806318f628d4146104a057610381565b80630135b1db1461038657806308c36874146103cb5780630962ef79146103f7575b600080fd5b34801561039257600080fd5b506103b9600480360360208110156103a957600080fd5b50356001600160a01b0316611003565b60408051918252519081900360200190f35b3480156103d757600080fd5b506103f5600480360360208110156103ee57600080fd5b5035611015565b005b34801561040357600080fd5b506103f56004803603602081101561041a57600080fd5b50356110e1565b34801561042d57600080fd5b5061043661122c565b604080516001600160a01b039092168252519081900360200190f35b34801561045e57600080fd5b506103b96004803603604081101561047557600080fd5b506001600160a01b03813516906020013561123b565b34801561049757600080fd5b506103b96112c4565b3480156104ac57600080fd5b506103f560048036036101208110156104c457600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e08101359061010001356112ca565b34801561051157600080fd5b506103b96004803603604081101561052857600080fd5b508035906020013561142c565b34801561054157600080fd5b506103f56004803603604081101561055857600080fd5b5080359060200135611656565b34801561057157600080fd5b506105a46004803603606081101561058857600080fd5b506001600160a01b03813516906020810135906040013561172f565b60408051938452602084019290925282820152519081900360600190f35b3480156105ce57600080fd5b506103f5600480360360808110156105e557600080fd5b506001600160a01b038135811691602081013590911690604081013515159060600135611761565b34801561061957600080fd5b506103b96118fe565b34801561062e57600080fd5b506103f56004803603602081101561064557600080fd5b50356001600160a01b0316611904565b34801561066157600080fd5b5061067f6004803603602081101561067857600080fd5b5035611997565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b3480156106c357600080fd5b506103f5600480360360608110156106da57600080fd5b506001600160a01b0381351690602081013590604001356119d9565b34801561070257600080fd5b506103f56004803603604081101561071957600080fd5b5080359060200135611d8a565b34801561073257600080fd5b506103f56004803603604081101561074957600080fd5b508035906020013561229a565b34801561076257600080fd5b506103f56004803603606081101561077957600080fd5b50803590602081013590604001356123de565b34801561079857600080fd5b506103f560048036036101008110156107b057600080fd5b6001600160a01b03823516916020810135918101906060810160408201356401000000008111156107e057600080fd5b8201836020820111156107f257600080fd5b8035906020019184600183028401116401000000008311171561081457600080fd5b919350915080359060208101359060408101359060608101359060800135612679565b34801561084357600080fd5b506103b96004803603602081101561085a57600080fd5b503561271f565b34801561086d57600080fd5b506103b96004803603604081101561088457600080fd5b5080359060200135612755565b34801561089d57600080fd5b506103b9612772565b3480156108b257600080fd5b506103b9600480360360408110156108c957600080fd5b506001600160a01b038135169060200135612778565b3480156108eb57600080fd5b506103b96004803603604081101561090257600080fd5b50803590602001356127b6565b34801561091b57600080fd5b506103b96004803603604081101561093257600080fd5b506001600160a01b0381351690602001356127d7565b34801561095457600080fd5b506103b96004803603604081101561096b57600080fd5b506001600160a01b038135169060200135612818565b34801561098d57600080fd5b506103f5612882565b3480156109a257600080fd5b506103b961293d565b3480156109b757600080fd5b506103b9612947565b3480156109cc57600080fd5b506109ea600480360360208110156109e357600080fd5b503561294d565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610a24578181015183820152602001610a0c565b50505050905090810190601f168015610a515780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610a6b57600080fd5b50610436612a06565b348015610a8057600080fd5b506103b9612a15565b348015610a9557600080fd5b506103f560048036036040811015610aac57600080fd5b506001600160a01b038135169060200135612a1b565b348015610ace57600080fd5b50610436612a7a565b348015610ae357600080fd5b50610aec612a89565b604080519115158252519081900360200190f35b348015610b0c57600080fd5b506103f560048036036020811015610b2357600080fd5b5035612a9a565b348015610b3657600080fd5b50610b6360048036036040811015610b4d57600080fd5b506001600160a01b038135169060200135612aff565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6103f560048036036020811015610b9f57600080fd5b5035612b31565b348015610bb257600080fd5b506103b960048036036040811015610bc957600080fd5b5080359060200135612b3c565b6103f560048036036020811015610bec57600080fd5b810190602081018135640100000000811115610c0757600080fd5b820183602082011115610c1957600080fd5b80359060200191846001830284011164010000000083111715610c3b57600080fd5b509092509050612b5d565b348015610c5257600080fd5b506103b960048036036040811015610c6957600080fd5b506001600160a01b038135169060200135612cca565b348015610c8b57600080fd5b50610ca960048036036020811015610ca257600080fd5b5035612ce7565b604080519788526020880196909652868601949094526060860192909252608085015260a08401526001600160a01b031660c0830152519081900360e00190f35b348015610cf657600080fd5b506105a460048036036040811015610d0d57600080fd5b506001600160a01b038135169060200135612d2d565b348015610d2f57600080fd5b50610d4d60048036036020811015610d4657600080fd5b5035612d59565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610d89578181015183820152602001610d71565b505050509050019250505060405180910390f35b348015610da957600080fd5b506103f560048036036060811015610dc057600080fd5b5080359060208101359060400135612dbe565b348015610ddf57600080fd5b50610aec60048036036020811015610df657600080fd5b5035612dd1565b348015610e0957600080fd5b50610436612de8565b348015610e1e57600080fd5b506103b960048036036020811015610e3557600080fd5b5035612df7565b348015610e4857600080fd5b506103b9612e09565b348015610e5d57600080fd5b506103f560048036036040811015610e7457600080fd5b50803590602001351515612e0f565b348015610e8f57600080fd5b506103b960048036036040811015610ea657600080fd5b506001600160a01b038135169060200135613047565b348015610ec857600080fd5b50610aec60048036036040811015610edf57600080fd5b506001600160a01b038135169060200135613064565b348015610f0157600080fd5b506103b96130fa565b348015610f1657600080fd5b506103b960048036036040811015610f2d57600080fd5b5080359060200135613100565b348015610f4657600080fd5b506103f560048036036060811015610f5d57600080fd5b5080359060208101359060400135613121565b348015610f7c57600080fd5b506103b960048036036040811015610f9357600080fd5b50803590602001356131dc565b348015610fac57600080fd5b506103b960048036036040811015610fc357600080fd5b50803590602001356131fd565b348015610fdc57600080fd5b506103f560048036036020811015610ff357600080fd5b50356001600160a01b031661321e565b60696020526000908152604090205481565b3361101e615024565b6110288284613280565b602081015181519192506000916110449163ffffffff6133e016565b905061106783856110628560400151856133e090919063ffffffff16565b61343a565b6001600160a01b0383166000818152607360209081526040808320888452825291829020805485019055845185820151868401518451928352928201528083019190915290518692917f4119153d17a36f9597d40e3ab4148d03261a439dddbec4e91799ab7159608e26919081900360600190a350505050565b336110ea615024565b6110f48284613280565b90506000826001600160a01b03166111318360400151611125856020015186600001516133e090919063ffffffff16565b9063ffffffff6133e016565b604051600081818185875af1925050503d806000811461116d576040519150601f19603f3d011682016040523d82523d6000602084013e611172565b606091505b50509050806111c8576040805162461bcd60e51b815260206004820152601260248201527f4661696c656420746f2073656e642046544d0000000000000000000000000000604482015290519081900360640190fd5b83836001600160a01b03167fc1d8eb6e444b89fb8ff0991c19311c070df704ccb009e210d1462d5b2410bf4584600001518560200151866040015160405180848152602001838152602001828152602001935050505060405180910390a350505050565b607b546001600160a01b031681565b60006112478383613064565b61127557506001600160a01b03821660009081526072602090815260408083208484529091529020546112be565b6001600160a01b0383166000818152607360209081526040808320868452825280832054938352607282528083208684529091529020546112bb9163ffffffff61354616565b90505b92915050565b60765481565b6112d333613588565b61130e5760405162461bcd60e51b81526004018080602001828103825260298152602001806151046029913960400191505060405180910390fd5b61131b898989600061359c565b6001600160a01b0389166000908152606f602090815260408083208b8452909152902060020181905561134d87613734565b851561142157868611156113925760405162461bcd60e51b815260040180806020018281038252602c8152602001806151c0602c913960400191505060405180910390fd5b6001600160a01b03891660008181526073602090815260408083208c845282528083208a8155600181018a90556002810189905560038101889055848452607483528184208d855283529281902086905580518781529182018a9052805192938c9390927f138940e95abffcd789b497bf6188bba3afa5fbd22fb5c42c2f6018d1bf0f4e7892908290030190a3505b505050505050505050565b33600081815260736020908152604080832086845290915281209091908361149b576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b6114a58286613064565b6114f6576040805162461bcd60e51b815260206004820152600d60248201527f6e6f74206c6f636b656420757000000000000000000000000000000000000000604482015290519081900360640190fd5b805484111561154c576040805162461bcd60e51b815260206004820152601760248201527f6e6f7420656e6f756768206c6f636b6564207374616b65000000000000000000604482015290519081900360640190fd5b61155682866137d2565b6115a7576040805162461bcd60e51b815260206004820152601860248201527f6f75747374616e64696e67207346544d2062616c616e63650000000000000000604482015290519081900360640190fd5b6115b1828661388d565b5060006115c48387878560000154613a58565b905081600301546363401ec501826002015410156115e0575060005b815485900382558015611603576115fa8387836001613b89565b61160381613d8f565b85836001600160a01b03167fef6c0c14fe9aa51af36acd791464dec3badbde668b63189b47bfa4e25be9b2b98784604051808381526020018281526020019250505060405180910390a395945050505050565b61165f33613588565b61169a5760405162461bcd60e51b81526004018080602001828103825260298152602001806151046029913960400191505060405180910390fd5b806116ec576040805162461bcd60e51b815260206004820152600c60248201527f77726f6e67207374617475730000000000000000000000000000000000000000604482015290519081900360640190fd5b6116f68282613df9565b611701826000612e0f565b6000828152606860205260408120600601546001600160a01b03169061172a9082908190613f23565b505050565b607160209081526000938452604080852082529284528284209052825290208054600182015460029092015490919083565b608254604080516001600160a01b03878116602483015286811660448084019190915283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f4a7702bb000000000000000000000000000000000000000000000000000000001781529251825160009592909216938693928291908083835b6020831061183057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016117f3565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d8060008114611893576040519150601f19603f3d011682016040523d82523d6000602084013e611898565b606091505b5050905080806118a6575082155b6118f7576040805162461bcd60e51b815260206004820152601b60248201527f676f7620766f746573207265636f756e74696e67206661696c65640000000000604482015290519081900360640190fd5b5050505050565b606d5481565b61190c612a89565b61195d576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b608380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b607760205280600052604060002060009150905080600701549080600801549080600901549080600a01549080600b01549080600c01549080600d0154905087565b6083546001600160a01b03163314611a38576040805162461bcd60e51b815260206004820152601260248201527f6e6f74207346544d2066696e616c697a65720000000000000000000000000000604482015290519081900360640190fd5b611a42838361388d565b5060008111611a98576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b607b54604080517f63d2bde50000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0386811660248301526044820186905260648201859052915191909216916363d2bde591608480830192600092919082900301818387803b158015611b1357600080fd5b505af1158015611b27573d6000803e3d6000fd5b505050506001600160a01b0383166000908152607260209081526040808320858452909152902054811115611ba3576040805162461bcd60e51b815260206004820152601060248201527f6e6f7420656e6f756768207374616b6500000000000000000000000000000000604482015290519081900360640190fd5b6000611baf848461123b565b905080821015611c3e576001600160a01b038416600090815260736020908152604080832086845290915290208054611bf09083850363ffffffff61354616565b815560408051838503815260006020820152815186926001600160a01b038916927fef6c0c14fe9aa51af36acd791464dec3badbde668b63189b47bfa4e25be9b2b9929081900390910190a3505b611c4b8484846001613b89565b611c56836000612e0f565b64ffffffffff83856001600160a01b03167fd3bb4e423fbea695d16b982f9f682dc5f35152e5411646a8a5a79a6b02ba8d57856040518082815260200191505060405180910390a4604051600090339084908381818185875af1925050503d8060008114611ce0576040519150601f19603f3d011682016040523d82523d6000602084013e611ce5565b606091505b5050905080611d3b576040805162461bcd60e51b815260206004820152601260248201527f4661696c656420746f2073656e642046544d0000000000000000000000000000604482015290519081900360640190fd5b64ffffffffff84866001600160a01b03167f75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21866040518082815260200191505060405180910390a45050505050565b33611d93615024565b506001600160a01b038116600090815260716020908152604080832086845282528083208584528252918290208251606081018452815480825260018301549382019390935260029091015492810192909252611e37576040805162461bcd60e51b815260206004820152601560248201527f7265717565737420646f65736e27742065786973740000000000000000000000604482015290519081900360640190fd5b611e4182856137d2565b611e92576040805162461bcd60e51b815260206004820152601860248201527f6f75747374616e64696e67207346544d2062616c616e63650000000000000000604482015290519081900360640190fd5b60208082015182516000878152606890935260409092206001015490919015801590611ece575060008681526068602052604090206001015482115b15611eef575050600084815260686020526040902060018101546002909101545b608160009054906101000a90046001600160a01b03166001600160a01b031663b82b84276040518163ffffffff1660e01b815260040160206040518083038186803b158015611f3d57600080fd5b505afa158015611f51573d6000803e3d6000fd5b505050506040513d6020811015611f6757600080fd5b50518201611f736140cd565b1015611fc6576040805162461bcd60e51b815260206004820152601660248201527f6e6f7420656e6f7567682074696d652070617373656400000000000000000000604482015290519081900360640190fd5b608160009054906101000a90046001600160a01b03166001600160a01b031663650acd666040518163ffffffff1660e01b815260040160206040518083038186803b15801561201457600080fd5b505afa158015612028573d6000803e3d6000fd5b505050506040513d602081101561203e57600080fd5b5051810161204a61293d565b101561209d576040805162461bcd60e51b815260206004820152601860248201527f6e6f7420656e6f7567682065706f636873207061737365640000000000000000604482015290519081900360640190fd5b6001600160a01b03841660009081526071602090815260408083208984528252808320888452909152812060020154906120d688612dd1565b905060006120f88383607a60008d8152602001908152602001600020546140d1565b6001600160a01b03881660009081526071602090815260408083208d845282528083208c845290915281208181556001810182905560020155606e805482019055905080831161218f576040805162461bcd60e51b815260206004820152601660248201527f7374616b652069732066756c6c7920736c617368656400000000000000000000604482015290519081900360640190fd5b60006001600160a01b0388166121ab858463ffffffff61354616565b604051600081818185875af1925050503d80600081146121e7576040519150601f19603f3d011682016040523d82523d6000602084013e6121ec565b606091505b5050905080612242576040805162461bcd60e51b815260206004820152601260248201527f4661696c656420746f2073656e642046544d0000000000000000000000000000604482015290519081900360640190fd5b61224b82613d8f565b888a896001600160a01b03167f75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21876040518082815260200191505060405180910390a450505050505050505050565b6122a2612a89565b6122f3576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6122fc82612dd1565b61234d576040805162461bcd60e51b815260206004820152601760248201527f76616c696461746f722069736e277420736c6173686564000000000000000000604482015290519081900360640190fd5b612355614133565b8111156123935760405162461bcd60e51b815260040180806020018281038252602181526020018061514e6021913960400191505060405180910390fd5b6000828152607a60209081526040918290208390558151838152915184927f047575f43f09a7a093d94ec483064acfc61b7e25c0de28017da442abf99cb91792908290030190a25050565b336123e9818561388d565b506000821161243f576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b612449818561123b565b82111561249d576040805162461bcd60e51b815260206004820152601960248201527f6e6f7420656e6f75676820756e6c6f636b6564207374616b6500000000000000604482015290519081900360640190fd5b6124a781856137d2565b6124f8576040805162461bcd60e51b815260206004820152601860248201527f6f75747374616e64696e67207346544d2062616c616e63650000000000000000604482015290519081900360640190fd5b6001600160a01b0381166000908152607160209081526040808320878452825280832086845290915290206002015415612579576040805162461bcd60e51b815260206004820152601360248201527f7772494420616c72656164792065786973747300000000000000000000000000604482015290519081900360640190fd5b6125868185846001613b89565b6001600160a01b0381166000908152607160209081526040808320878452825280832086845290915290206002018290556125bf61293d565b6001600160a01b038216600090815260716020908152604080832088845282528083208784529091529020556125f36140cd565b6001600160a01b03821660009081526071602090815260408083208884528252808320878452909152812060010191909155612630908590612e0f565b8284826001600160a01b03167fd3bb4e423fbea695d16b982f9f682dc5f35152e5411646a8a5a79a6b02ba8d57856040518082815260200191505060405180910390a450505050565b61268233613588565b6126bd5760405162461bcd60e51b81526004018080602001828103825260298152602001806151046029913960400191505060405180910390fd5b612705898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a9150899050888861413f565b606b5488111561142157606b889055505050505050505050565b6000818152606860209081526040808320600601546001600160a01b03168352607282528083208484529091529020545b919050565b600091825260776020908152604080842092845291905290205490565b606e5481565b6000612782615024565b61278c8484614306565b8051602082015160408301519293506127ae926111259163ffffffff6133e016565b949350505050565b60009182526077602090815260408084209284526001909201905290205490565b60006127e38383613064565b6127ef575060006112be565b506001600160a01b03919091166000908152607360209081526040808320938352929052205490565b6000612822615024565b506001600160a01b0383166000908152606f60209081526040808320858452825291829020825160608101845281548082526001830154938201849052600290920154938101849052926127ae929091611125919063ffffffff6133e016565b61288a612a89565b6128db576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6067546001015b90565b60675481565b606a6020908152600091825260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600186161502019093169290920491820184900484028101840190945280845290918301828280156129fe5780601f106129d3576101008083540402835291602001916129fe565b820191906000526020600020905b8154815290600101906020018083116129e157829003601f168201915b505050505081565b6082546001600160a01b031681565b606c5481565b612a25828261388d565b612a76576040805162461bcd60e51b815260206004820152601060248201527f6e6f7468696e6720746f20737461736800000000000000000000000000000000604482015290519081900360640190fd5b5050565b6033546001600160a01b031690565b6033546001600160a01b0316331490565b612aa2612a89565b612af3576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b612afc81613d8f565b50565b607360209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b612afc33823461343a565b60009182526077602090815260408084209284526005909201905290205490565b608160009054906101000a90046001600160a01b03166001600160a01b031663c5f530af6040518163ffffffff1660e01b815260040160206040518083038186803b158015612bab57600080fd5b505afa158015612bbf573d6000803e3d6000fd5b505050506040513d6020811015612bd557600080fd5b5051341015612c2b576040805162461bcd60e51b815260206004820152601760248201527f696e73756666696369656e742073656c662d7374616b65000000000000000000604482015290519081900360640190fd5b80612c7d576040805162461bcd60e51b815260206004820152600c60248201527f656d707479207075626b65790000000000000000000000000000000000000000604482015290519081900360640190fd5b612cbd3383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061437492505050565b612a7633606b543461343a565b607060209081526000928352604080842090915290825290205481565b606860205260009081526040902080546001820154600283015460038401546004850154600586015460069096015494959394929391929091906001600160a01b031687565b607460209081526000928352604080842090915290825290208054600182015460029092015490919083565b600081815260776020908152604091829020600601805483518184028101840190945280845260609392830182828015612db257602002820191906000526020600020905b815481526020019060010190808311612d9e575b50505050509050919050565b33612dcb8185858561439f565b50505050565b600090815260686020526040902054608016151590565b607f546001600160a01b031681565b607a6020526000908152604090205481565b606b5481565b612e1882614754565b612e69576040805162461bcd60e51b815260206004820152601760248201527f76616c696461746f7220646f65736e2774206578697374000000000000000000604482015290519081900360640190fd5b60008281526068602052604090206003810154905415612e87575060005b606654604080517fa4066fbe000000000000000000000000000000000000000000000000000000008152600481018690526024810184905290516001600160a01b039092169163a4066fbe9160448082019260009290919082900301818387803b158015612ef457600080fd5b505af1158015612f08573d6000803e3d6000fd5b50505050818015612f1857508015155b1561172a576066546000848152606a60205260409081902081517f242a6e3f0000000000000000000000000000000000000000000000000000000081526004810187815260248201938452825460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001831615610100020190911604604483018190526001600160a01b039095169463242a6e3f948994939091606490910190849080156130095780601f10612fde57610100808354040283529160200191613009565b820191906000526020600020905b815481529060010190602001808311612fec57829003601f168201915b50509350505050600060405180830381600087803b15801561302a57600080fd5b505af115801561303e573d6000803e3d6000fd5b50505050505050565b607260209081526000928352604080842090915290825290205481565b6001600160a01b0382166000908152607360209081526040808320848452909152812060020154158015906130bb57506001600160a01b038316600090815260736020908152604080832085845290915290205415155b80156112bb57506001600160a01b03831660009081526073602090815260408083208584529091529020600201546130f16140cd565b11159392505050565b607e5481565b60009182526077602090815260408084209284526003909201905290205490565b3381613174576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b61317e8185613064565b156131d0576040805162461bcd60e51b815260206004820152601160248201527f616c7265616479206c6f636b6564207570000000000000000000000000000000604482015290519081900360640190fd5b612dcb8185858561439f565b60009182526077602090815260408084209284526002909201905290205490565b60009182526077602090815260408084209284526004909201905290205490565b613226612a89565b613277576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b612afc8161476b565b613288615024565b61329283836137d2565b6132e3576040805162461bcd60e51b815260206004820152601860248201527f6f75747374616e64696e67207346544d2062616c616e63650000000000000000604482015290519081900360640190fd5b6132ed838361388d565b50506001600160a01b0382166000908152606f602090815260408083208484528252808320815160608101835281548082526001830154948201859052600290920154928101839052939261334b926111259163ffffffff6133e016565b90508061339f576040805162461bcd60e51b815260206004820152600c60248201527f7a65726f20726577617264730000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b0384166000908152606f60209081526040808320868452909152812081815560018101829055600201556133d981613734565b5092915050565b6000828201838110156112bb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b61344382614754565b613494576040805162461bcd60e51b815260206004820152601760248201527f76616c696461746f7220646f65736e2774206578697374000000000000000000604482015290519081900360640190fd5b600082815260686020526040902054156134f5576040805162461bcd60e51b815260206004820152601660248201527f76616c696461746f722069736e27742061637469766500000000000000000000604482015290519081900360640190fd5b613502838383600161359c565b61350b82614824565b61172a5760405162461bcd60e51b81526004018080602001828103825260298152602001806151976029913960400191505060405180910390fd5b60006112bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506148ec565b6066546001600160a01b0390811691161490565b600082116135f1576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b6135fb848461388d565b506001600160a01b0384166000908152607260209081526040808320868452909152902054613630908363ffffffff6133e016565b6001600160a01b0385166000908152607260209081526040808320878452825280832093909355606890522060030154613670818463ffffffff6133e016565b600085815260686020526040902060030155606c54613695908463ffffffff6133e016565b606c556000848152606860205260409020546136c257606d546136be908463ffffffff6133e016565b606d555b6136cd848215612e0f565b60408051848152905185916001600160a01b038816917f9a8f44850296624dadfd9c246d17e47171d35727a181bd090aa14bbbe00238bb9181900360200190a36000848152606860205260409020600601546118f79086906001600160a01b031684613f23565b606654604080517f66e7ea0f0000000000000000000000000000000000000000000000000000000081523060048201526024810184905290516001600160a01b03909216916366e7ea0f9160448082019260009290919082900301818387803b1580156137a057600080fd5b505af11580156137b4573d6000803e3d6000fd5b50506076546137cc925090508263ffffffff6133e016565b60765550565b607b546000906001600160a01b03166137ed575060016112be565b607b54604080517f21d585c30000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015260248201869052915191909216916321d585c3916044808301926020929190829003018186803b15801561385a57600080fd5b505afa15801561386e573d6000803e3d6000fd5b505050506040513d602081101561388457600080fd5b50519392505050565b6000613897615024565b6138a18484614983565b90506138ac83614abb565b6001600160a01b0385166000818152607060209081526040808320888452825280832094909455918152606f8252828120868252825282902082516060810184528154815260018201549281019290925260020154918101919091526139129082614b16565b6001600160a01b0385166000818152606f602090815260408083208884528252808320855181558583015160018083019190915595820151600291820155938352607482528083208884528252918290208251606081018452815481529481015491850191909152909101549082015261398c9082614b16565b6001600160a01b0385166000908152607460209081526040808320878452825291829020835181559083015160018201559101516002909101556139d08484613064565b613a33576001600160a01b0384166000818152607360209081526040808320878452825280832083815560018082018590556002808301869055600390920185905594845260748352818420888552909252822082815592830182905591909101555b6020810151151580613a455750805115155b806127ae57506040015115159392505050565b6001600160a01b03841660009081526074602090815260408083208684529091528120548190613aa0908490613a94908763ffffffff614b8816565b9063ffffffff614be116565b6001600160a01b038716600090815260746020908152604080832089845290915281206001015491925090613ae1908590613a94908863ffffffff614b8816565b6001600160a01b03881660009081526074602090815260408083208a845290915290205490915060028204830190613b199084613546565b6001600160a01b03891660009081526074602090815260408083208b8452909152902090815560010154613b4d9083613546565b6001600160a01b03891660009081526074602090815260408083208b8452909152902060010155858110613b7e5750845b979650505050505050565b6001600160a01b03841660009081526072602090815260408083208684528252808320805486900390556068909152902060030154613bce908363ffffffff61354616565b600084815260686020526040902060030155606c54613bf3908363ffffffff61354616565b606c55600083815260686020526040902054613c2057606d54613c1c908363ffffffff61354616565b606d555b6000613c2b8461271f565b90508015613d5d57600084815260686020526040902054613d5857608160009054906101000a90046001600160a01b03166001600160a01b031663c5f530af6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c9457600080fd5b505afa158015613ca8573d6000803e3d6000fd5b505050506040513d6020811015613cbe57600080fd5b5051811015613d14576040805162461bcd60e51b815260206004820152601760248201527f696e73756666696369656e742073656c662d7374616b65000000000000000000604482015290519081900360640190fd5b613d1d84614824565b613d585760405162461bcd60e51b81526004018080602001828103825260298152602001806151976029913960400191505060405180910390fd5b613d68565b613d68846001613df9565b6000848152606860205260409020600601546118f79086906001600160a01b031684613f23565b8015612afc5760405160009082156108fc0290839083818181858288f19350505050158015613dc2573d6000803e3d6000fd5b506040805182815290517f8918bd6046d08b314e457977f29562c5d76a7030d79b1edba66e8a5da0b77ae89181900360200190a150565b600082815260686020526040902054158015613e1457508015155b15613e4157600082815260686020526040902060030154606d54613e3d9163ffffffff61354616565b606d555b600082815260686020526040902054811115612a7657600082815260686020526040902081815560020154613ee957613e7861293d565b600083815260686020526040902060020155613e926140cd565b6000838152606860209081526040918290206001810184905560020154825190815290810192909252805184927fac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e4792908290030190a25b60408051828152905183917fcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e919081900360200190a25050565b6082546001600160a01b03161561172a57608254604080516001600160a01b03868116602483015285811660448084019190915283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f4a7702bb00000000000000000000000000000000000000000000000000000000178152925182516000959290921693627a120093928291908083835b6020831061400657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613fc9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d8060008114614069576040519150601f19603f3d011682016040523d82523d6000602084013e61406e565b606091505b50509050808061407c575081155b612dcb576040805162461bcd60e51b815260206004820152601b60248201527f676f7620766f746573207265636f756e74696e67206661696c65640000000000604482015290519081900360640190fd5b4290565b60008215806140e757506140e3614133565b8210155b156140f45750600061412c565b61411f6001611125614104614133565b613a9486614110614133565b8a91900363ffffffff614b8816565b90508381111561412c5750825b9392505050565b670de0b6b3a764000090565b6001600160a01b038816600090815260696020526040902054156141aa576040805162461bcd60e51b815260206004820152601860248201527f76616c696461746f7220616c7265616479206578697374730000000000000000604482015290519081900360640190fd5b6001600160a01b03881660008181526069602090815260408083208b90558a8352606882528083208981556004810189905560058101889055600181018690556002810187905560060180547fffffffffffffffffffffffff000000000000000000000000000000000000000016909417909355606a8152919020875161423392890190615045565b50876001600160a01b0316877f49bca1ed2666922f9f1690c26a569e1299c2a715fe57647d77e81adfabbf25bf8686604051808381526020018281526020019250505060405180910390a381156142bf576040805183815260208101839052815189927fac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e47928290030190a25b84156142fc5760408051868152905188917fcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e919081900360200190a25b5050505050505050565b61430e615024565b614316615024565b6143208484614983565b6001600160a01b0385166000908152606f6020908152604080832087845282529182902082516060810184528154815260018201549281019290925260020154918101919091529091506127ae9082614b16565b606b80546001019081905561172a838284600061438f61293d565b6143976140cd565b60008061413f565b6143a9848461123b565b8111156143fd576040805162461bcd60e51b815260206004820152601060248201527f6e6f7420656e6f756768207374616b6500000000000000000000000000000000604482015290519081900360640190fd5b6000838152606860205260409020541561445e576040805162461bcd60e51b815260206004820152601660248201527f76616c696461746f722069736e27742061637469766500000000000000000000604482015290519081900360640190fd5b608160009054906101000a90046001600160a01b03166001600160a01b0316630d7b26096040518163ffffffff1660e01b815260040160206040518083038186803b1580156144ac57600080fd5b505afa1580156144c0573d6000803e3d6000fd5b505050506040513d60208110156144d657600080fd5b505182108015906145605750608160009054906101000a90046001600160a01b03166001600160a01b0316630d4955e36040518163ffffffff1660e01b815260040160206040518083038186803b15801561453057600080fd5b505afa158015614544573d6000803e3d6000fd5b505050506040513d602081101561455a57600080fd5b50518211155b6145b1576040805162461bcd60e51b815260206004820152601260248201527f696e636f7272656374206475726174696f6e0000000000000000000000000000604482015290519081900360640190fd5b60006145bf836111256140cd565b6000858152606860205260409020600601549091506001600160a01b03908116908616811461464d576001600160a01b038116600090815260736020908152604080832088845290915290206002015482111561464d5760405162461bcd60e51b815260040180806020018281038252602881526020018061516f6028913960400191505060405180910390fd5b614657868661388d565b506001600160a01b0386166000908152607360209081526040808320888452909152902060038101548510156146d4576040805162461bcd60e51b815260206004820152601f60248201527f6c6f636b7570206475726174696f6e2063616e6e6f7420646563726561736500604482015290519081900360640190fd5b80546146e6908563ffffffff6133e016565b81556146f061293d565b600182015560028101839055600381018590556040805186815260208101869052815188926001600160a01b038b16927f138940e95abffcd789b497bf6188bba3afa5fbd22fb5c42c2f6018d1bf0f4e78929081900390910190a350505050505050565b600090815260686020526040902060050154151590565b6001600160a01b0381166147b05760405162461bcd60e51b81526004018080602001828103825260268152602001806150de6026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60006148d1614831614133565b608154604080517f2265f2840000000000000000000000000000000000000000000000000000000081529051613a94926001600160a01b031691632265f284916004808301926020929190829003018186803b15801561489057600080fd5b505afa1580156148a4573d6000803e3d6000fd5b505050506040513d60208110156148ba57600080fd5b50516148c58661271f565b9063ffffffff614b8816565b60008381526068602052604090206003015411159050919050565b6000818484111561497b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614940578181015183820152602001614928565b50505050905090810190601f16801561496d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b61498b615024565b6001600160a01b0383166000908152607060209081526040808320858452909152812054906149b984614abb565b905060006149c78686614c23565b9050818111156149d45750805b828110156149df5750815b6001600160a01b03861660008181526073602090815260408083208984528252808320938352607282528083208984529091528120548254909190614a2b90839063ffffffff61354616565b90506000614a3f84600001548a8988614d00565b9050614a49615024565b614a57828660030154614d63565b9050614a65838b8a89614d00565b9150614a6f615024565b614a7a836000614d63565b9050614a88858c898b614d00565b9250614a92615024565b614a9d846000614d63565b9050614aaa838383614f24565b9d9c50505050505050505050505050565b60008181526068602052604081206002015415614b0e576000828152606860205260409020600201546067541015614af65750606754612750565b50600081815260686020526040902060020154612750565b505060675490565b614b1e615024565b6040805160608101909152825184518291614b3f919063ffffffff6133e016565b8152602001614b5f846020015186602001516133e090919063ffffffff16565b8152602001614b7f846040015186604001516133e090919063ffffffff16565b90529392505050565b600082614b97575060006112be565b82820282848281614ba457fe5b04146112bb5760405162461bcd60e51b815260040180806020018281038252602181526020018061512d6021913960400191505060405180910390fd5b60006112bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614f3f565b6001600160a01b0382166000908152607360209081526040808320848452909152812060010154606754614c58858583614fa4565b15614c665791506112be9050565b614c71858584614fa4565b614c80576000925050506112be565b80821115614c93576000925050506112be565b80821015614cc657600281830104614cac868683614fa4565b15614cbc57806001019250614cc0565b8091505b50614c93565b80614cd6576000925050506112be565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01949350505050565b6000818310614d11575060006127ae565b600083815260776020818152604080842088855260019081018352818520548786529383528185208986520190915290912054613b7e614d4f614133565b613a94896148c5858763ffffffff61354616565b614d6b615024565b60405180606001604052806000815260200160008152602001600081525090506000608160009054906101000a90046001600160a01b03166001600160a01b0316635e2308d26040518163ffffffff1660e01b815260040160206040518083038186803b158015614ddb57600080fd5b505afa158015614def573d6000803e3d6000fd5b505050506040513d6020811015614e0557600080fd5b505190508215614efd57600081614e1a614133565b0390506000614eac608160009054906101000a90046001600160a01b03166001600160a01b0316630d4955e36040518163ffffffff1660e01b815260040160206040518083038186803b158015614e7057600080fd5b505afa158015614e84573d6000803e3d6000fd5b505050506040513d6020811015614e9a57600080fd5b5051613a94848863ffffffff614b8816565b90506000614ecd614ebb614133565b613a948987860163ffffffff614b8816565b9050614eea614eda614133565b613a94898763ffffffff614b8816565b6020860181905290038452506133d99050565b614f18614f08614133565b613a94868463ffffffff614b8816565b60408301525092915050565b614f2c615024565b6127ae614f398585614b16565b83614b16565b60008183614f8e5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614940578181015183820152602001614928565b506000838581614f9a57fe5b0495945050505050565b6001600160a01b038316600090815260736020908152604080832085845290915281206001015482108015906127ae57506001600160a01b03841660009081526073602090815260408083208684529091529020600201546150058361500f565b1115949350505050565b60009081526077602052604090206007015490565b60405180606001604052806000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061508657805160ff19168380011785556150b3565b828001600101855582156150b3579182015b828111156150b3578251825591602001919060010190615098565b506150bf9291506150c3565b5090565b61294491905b808211156150bf57600081556001016150c956fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737363616c6c6572206973206e6f7420746865204e6f64654472697665724175746820636f6e7472616374536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f776d757374206265206c657373207468616e206f7220657175616c20746f20312e3076616c696461746f72206c6f636b757020706572696f642077696c6c20656e64206561726c69657276616c696461746f7227732064656c65676174696f6e73206c696d69742069732065786365656465646c6f636b6564207374616b652069732067726561746572207468616e207468652077686f6c65207374616b65a265627a7a72315820b767b9bd00adb5f0467097fa60a9e2cfcb624e12e00375239584e1338e314fe964736f6c63430005110032", -} - -// ContractABI is the input ABI used to generate the binding from. -// Deprecated: Use ContractMetaData.ABI instead. -var ContractABI = ContractMetaData.ABI - -// ContractBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ContractMetaData.Bin instead. -var ContractBin = ContractMetaData.Bin - -// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. -func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Contract, error) { - parsed, err := ContractMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// Contract is an auto generated Go binding around an Ethereum contract. -type Contract struct { - ContractCaller // Read-only binding to the contract - ContractTransactor // Write-only binding to the contract - ContractFilterer // Log filterer for contract events -} - -// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. -type ContractCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ContractTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ContractFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ContractSession struct { - Contract *Contract // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ContractCallerSession struct { - Contract *ContractCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ContractTransactorSession struct { - Contract *ContractTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. -type ContractRaw struct { - Contract *Contract // Generic contract binding to access the raw methods on -} - -// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ContractCallerRaw struct { - Contract *ContractCaller // Generic read-only contract binding to access the raw methods on -} - -// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ContractTransactorRaw struct { - Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewContract creates a new instance of Contract, bound to a specific deployed contract. -func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { - contract, err := bindContract(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. -func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { - contract, err := bindContract(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ContractCaller{contract: contract}, nil -} - -// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. -func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { - contract, err := bindContract(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ContractTransactor{contract: contract}, nil -} - -// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. -func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { - contract, err := bindContract(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ContractFilterer{contract: contract}, nil -} - -// bindContract binds a generic wrapper to an already deployed contract. -func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ContractABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.contract.Transact(opts, method, params...) -} - -// CurrentEpoch is a free data retrieval call binding the contract method 0x76671808. -// -// Solidity: function currentEpoch() view returns(uint256) -func (_Contract *ContractCaller) CurrentEpoch(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "currentEpoch") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// CurrentEpoch is a free data retrieval call binding the contract method 0x76671808. -// -// Solidity: function currentEpoch() view returns(uint256) -func (_Contract *ContractSession) CurrentEpoch() (*big.Int, error) { - return _Contract.Contract.CurrentEpoch(&_Contract.CallOpts) -} - -// CurrentEpoch is a free data retrieval call binding the contract method 0x76671808. -// -// Solidity: function currentEpoch() view returns(uint256) -func (_Contract *ContractCallerSession) CurrentEpoch() (*big.Int, error) { - return _Contract.Contract.CurrentEpoch(&_Contract.CallOpts) -} - -// CurrentSealedEpoch is a free data retrieval call binding the contract method 0x7cacb1d6. -// -// Solidity: function currentSealedEpoch() view returns(uint256) -func (_Contract *ContractCaller) CurrentSealedEpoch(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "currentSealedEpoch") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// CurrentSealedEpoch is a free data retrieval call binding the contract method 0x7cacb1d6. -// -// Solidity: function currentSealedEpoch() view returns(uint256) -func (_Contract *ContractSession) CurrentSealedEpoch() (*big.Int, error) { - return _Contract.Contract.CurrentSealedEpoch(&_Contract.CallOpts) -} - -// CurrentSealedEpoch is a free data retrieval call binding the contract method 0x7cacb1d6. -// -// Solidity: function currentSealedEpoch() view returns(uint256) -func (_Contract *ContractCallerSession) CurrentSealedEpoch() (*big.Int, error) { - return _Contract.Contract.CurrentSealedEpoch(&_Contract.CallOpts) -} - -// GetEpochAccumulatedOriginatedTxsFee is a free data retrieval call binding the contract method 0xdc31e1af. -// -// Solidity: function getEpochAccumulatedOriginatedTxsFee(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCaller) GetEpochAccumulatedOriginatedTxsFee(opts *bind.CallOpts, epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getEpochAccumulatedOriginatedTxsFee", epoch, validatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetEpochAccumulatedOriginatedTxsFee is a free data retrieval call binding the contract method 0xdc31e1af. -// -// Solidity: function getEpochAccumulatedOriginatedTxsFee(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractSession) GetEpochAccumulatedOriginatedTxsFee(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochAccumulatedOriginatedTxsFee(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochAccumulatedOriginatedTxsFee is a free data retrieval call binding the contract method 0xdc31e1af. -// -// Solidity: function getEpochAccumulatedOriginatedTxsFee(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetEpochAccumulatedOriginatedTxsFee(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochAccumulatedOriginatedTxsFee(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochAccumulatedRewardPerToken is a free data retrieval call binding the contract method 0x61e53fcc. -// -// Solidity: function getEpochAccumulatedRewardPerToken(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCaller) GetEpochAccumulatedRewardPerToken(opts *bind.CallOpts, epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getEpochAccumulatedRewardPerToken", epoch, validatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetEpochAccumulatedRewardPerToken is a free data retrieval call binding the contract method 0x61e53fcc. -// -// Solidity: function getEpochAccumulatedRewardPerToken(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractSession) GetEpochAccumulatedRewardPerToken(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochAccumulatedRewardPerToken(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochAccumulatedRewardPerToken is a free data retrieval call binding the contract method 0x61e53fcc. -// -// Solidity: function getEpochAccumulatedRewardPerToken(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetEpochAccumulatedRewardPerToken(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochAccumulatedRewardPerToken(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochAccumulatedUptime is a free data retrieval call binding the contract method 0xdf00c922. -// -// Solidity: function getEpochAccumulatedUptime(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCaller) GetEpochAccumulatedUptime(opts *bind.CallOpts, epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getEpochAccumulatedUptime", epoch, validatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetEpochAccumulatedUptime is a free data retrieval call binding the contract method 0xdf00c922. -// -// Solidity: function getEpochAccumulatedUptime(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractSession) GetEpochAccumulatedUptime(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochAccumulatedUptime(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochAccumulatedUptime is a free data retrieval call binding the contract method 0xdf00c922. -// -// Solidity: function getEpochAccumulatedUptime(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetEpochAccumulatedUptime(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochAccumulatedUptime(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochOfflineBlocks is a free data retrieval call binding the contract method 0xa198d229. -// -// Solidity: function getEpochOfflineBlocks(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCaller) GetEpochOfflineBlocks(opts *bind.CallOpts, epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getEpochOfflineBlocks", epoch, validatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetEpochOfflineBlocks is a free data retrieval call binding the contract method 0xa198d229. -// -// Solidity: function getEpochOfflineBlocks(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractSession) GetEpochOfflineBlocks(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochOfflineBlocks(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochOfflineBlocks is a free data retrieval call binding the contract method 0xa198d229. -// -// Solidity: function getEpochOfflineBlocks(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetEpochOfflineBlocks(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochOfflineBlocks(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochOfflineTime is a free data retrieval call binding the contract method 0xe261641a. -// -// Solidity: function getEpochOfflineTime(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCaller) GetEpochOfflineTime(opts *bind.CallOpts, epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getEpochOfflineTime", epoch, validatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetEpochOfflineTime is a free data retrieval call binding the contract method 0xe261641a. -// -// Solidity: function getEpochOfflineTime(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractSession) GetEpochOfflineTime(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochOfflineTime(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochOfflineTime is a free data retrieval call binding the contract method 0xe261641a. -// -// Solidity: function getEpochOfflineTime(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetEpochOfflineTime(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochOfflineTime(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochReceivedStake is a free data retrieval call binding the contract method 0x58f95b80. -// -// Solidity: function getEpochReceivedStake(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCaller) GetEpochReceivedStake(opts *bind.CallOpts, epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getEpochReceivedStake", epoch, validatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetEpochReceivedStake is a free data retrieval call binding the contract method 0x58f95b80. -// -// Solidity: function getEpochReceivedStake(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractSession) GetEpochReceivedStake(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochReceivedStake(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochReceivedStake is a free data retrieval call binding the contract method 0x58f95b80. -// -// Solidity: function getEpochReceivedStake(uint256 epoch, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetEpochReceivedStake(epoch *big.Int, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetEpochReceivedStake(&_Contract.CallOpts, epoch, validatorID) -} - -// GetEpochSnapshot is a free data retrieval call binding the contract method 0x39b80c00. -// -// Solidity: function getEpochSnapshot(uint256 ) view returns(uint256 endTime, uint256 epochFee, uint256 totalBaseRewardWeight, uint256 totalTxRewardWeight, uint256 baseRewardPerSecond, uint256 totalStake, uint256 totalSupply) -func (_Contract *ContractCaller) GetEpochSnapshot(opts *bind.CallOpts, arg0 *big.Int) (struct { - EndTime *big.Int - EpochFee *big.Int - TotalBaseRewardWeight *big.Int - TotalTxRewardWeight *big.Int - BaseRewardPerSecond *big.Int - TotalStake *big.Int - TotalSupply *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getEpochSnapshot", arg0) - - outstruct := new(struct { - EndTime *big.Int - EpochFee *big.Int - TotalBaseRewardWeight *big.Int - TotalTxRewardWeight *big.Int - BaseRewardPerSecond *big.Int - TotalStake *big.Int - TotalSupply *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.EndTime = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.EpochFee = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.TotalBaseRewardWeight = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.TotalTxRewardWeight = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - outstruct.BaseRewardPerSecond = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) - outstruct.TotalStake = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) - outstruct.TotalSupply = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// GetEpochSnapshot is a free data retrieval call binding the contract method 0x39b80c00. -// -// Solidity: function getEpochSnapshot(uint256 ) view returns(uint256 endTime, uint256 epochFee, uint256 totalBaseRewardWeight, uint256 totalTxRewardWeight, uint256 baseRewardPerSecond, uint256 totalStake, uint256 totalSupply) -func (_Contract *ContractSession) GetEpochSnapshot(arg0 *big.Int) (struct { - EndTime *big.Int - EpochFee *big.Int - TotalBaseRewardWeight *big.Int - TotalTxRewardWeight *big.Int - BaseRewardPerSecond *big.Int - TotalStake *big.Int - TotalSupply *big.Int -}, error) { - return _Contract.Contract.GetEpochSnapshot(&_Contract.CallOpts, arg0) -} - -// GetEpochSnapshot is a free data retrieval call binding the contract method 0x39b80c00. -// -// Solidity: function getEpochSnapshot(uint256 ) view returns(uint256 endTime, uint256 epochFee, uint256 totalBaseRewardWeight, uint256 totalTxRewardWeight, uint256 baseRewardPerSecond, uint256 totalStake, uint256 totalSupply) -func (_Contract *ContractCallerSession) GetEpochSnapshot(arg0 *big.Int) (struct { - EndTime *big.Int - EpochFee *big.Int - TotalBaseRewardWeight *big.Int - TotalTxRewardWeight *big.Int - BaseRewardPerSecond *big.Int - TotalStake *big.Int - TotalSupply *big.Int -}, error) { - return _Contract.Contract.GetEpochSnapshot(&_Contract.CallOpts, arg0) -} - -// GetEpochValidatorIDs is a free data retrieval call binding the contract method 0xb88a37e2. -// -// Solidity: function getEpochValidatorIDs(uint256 epoch) view returns(uint256[]) -func (_Contract *ContractCaller) GetEpochValidatorIDs(opts *bind.CallOpts, epoch *big.Int) ([]*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getEpochValidatorIDs", epoch) - - if err != nil { - return *new([]*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) - - return out0, err - -} - -// GetEpochValidatorIDs is a free data retrieval call binding the contract method 0xb88a37e2. -// -// Solidity: function getEpochValidatorIDs(uint256 epoch) view returns(uint256[]) -func (_Contract *ContractSession) GetEpochValidatorIDs(epoch *big.Int) ([]*big.Int, error) { - return _Contract.Contract.GetEpochValidatorIDs(&_Contract.CallOpts, epoch) -} - -// GetEpochValidatorIDs is a free data retrieval call binding the contract method 0xb88a37e2. -// -// Solidity: function getEpochValidatorIDs(uint256 epoch) view returns(uint256[]) -func (_Contract *ContractCallerSession) GetEpochValidatorIDs(epoch *big.Int) ([]*big.Int, error) { - return _Contract.Contract.GetEpochValidatorIDs(&_Contract.CallOpts, epoch) -} - -// GetLockedStake is a free data retrieval call binding the contract method 0x670322f8. -// -// Solidity: function getLockedStake(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractCaller) GetLockedStake(opts *bind.CallOpts, delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getLockedStake", delegator, toValidatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetLockedStake is a free data retrieval call binding the contract method 0x670322f8. -// -// Solidity: function getLockedStake(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractSession) GetLockedStake(delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetLockedStake(&_Contract.CallOpts, delegator, toValidatorID) -} - -// GetLockedStake is a free data retrieval call binding the contract method 0x670322f8. -// -// Solidity: function getLockedStake(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetLockedStake(delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetLockedStake(&_Contract.CallOpts, delegator, toValidatorID) -} - -// GetLockupInfo is a free data retrieval call binding the contract method 0x96c7ee46. -// -// Solidity: function getLockupInfo(address , uint256 ) view returns(uint256 lockedStake, uint256 fromEpoch, uint256 endTime, uint256 duration) -func (_Contract *ContractCaller) GetLockupInfo(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (struct { - LockedStake *big.Int - FromEpoch *big.Int - EndTime *big.Int - Duration *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getLockupInfo", arg0, arg1) - - outstruct := new(struct { - LockedStake *big.Int - FromEpoch *big.Int - EndTime *big.Int - Duration *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.LockedStake = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.FromEpoch = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.EndTime = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.Duration = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// GetLockupInfo is a free data retrieval call binding the contract method 0x96c7ee46. -// -// Solidity: function getLockupInfo(address , uint256 ) view returns(uint256 lockedStake, uint256 fromEpoch, uint256 endTime, uint256 duration) -func (_Contract *ContractSession) GetLockupInfo(arg0 common.Address, arg1 *big.Int) (struct { - LockedStake *big.Int - FromEpoch *big.Int - EndTime *big.Int - Duration *big.Int -}, error) { - return _Contract.Contract.GetLockupInfo(&_Contract.CallOpts, arg0, arg1) -} - -// GetLockupInfo is a free data retrieval call binding the contract method 0x96c7ee46. -// -// Solidity: function getLockupInfo(address , uint256 ) view returns(uint256 lockedStake, uint256 fromEpoch, uint256 endTime, uint256 duration) -func (_Contract *ContractCallerSession) GetLockupInfo(arg0 common.Address, arg1 *big.Int) (struct { - LockedStake *big.Int - FromEpoch *big.Int - EndTime *big.Int - Duration *big.Int -}, error) { - return _Contract.Contract.GetLockupInfo(&_Contract.CallOpts, arg0, arg1) -} - -// GetSelfStake is a free data retrieval call binding the contract method 0x5601fe01. -// -// Solidity: function getSelfStake(uint256 validatorID) view returns(uint256) -func (_Contract *ContractCaller) GetSelfStake(opts *bind.CallOpts, validatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getSelfStake", validatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetSelfStake is a free data retrieval call binding the contract method 0x5601fe01. -// -// Solidity: function getSelfStake(uint256 validatorID) view returns(uint256) -func (_Contract *ContractSession) GetSelfStake(validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetSelfStake(&_Contract.CallOpts, validatorID) -} - -// GetSelfStake is a free data retrieval call binding the contract method 0x5601fe01. -// -// Solidity: function getSelfStake(uint256 validatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetSelfStake(validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetSelfStake(&_Contract.CallOpts, validatorID) -} - -// GetStake is a free data retrieval call binding the contract method 0xcfd47663. -// -// Solidity: function getStake(address , uint256 ) view returns(uint256) -func (_Contract *ContractCaller) GetStake(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getStake", arg0, arg1) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetStake is a free data retrieval call binding the contract method 0xcfd47663. -// -// Solidity: function getStake(address , uint256 ) view returns(uint256) -func (_Contract *ContractSession) GetStake(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - return _Contract.Contract.GetStake(&_Contract.CallOpts, arg0, arg1) -} - -// GetStake is a free data retrieval call binding the contract method 0xcfd47663. -// -// Solidity: function getStake(address , uint256 ) view returns(uint256) -func (_Contract *ContractCallerSession) GetStake(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - return _Contract.Contract.GetStake(&_Contract.CallOpts, arg0, arg1) -} - -// GetStashedLockupRewards is a free data retrieval call binding the contract method 0xb810e411. -// -// Solidity: function getStashedLockupRewards(address , uint256 ) view returns(uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractCaller) GetStashedLockupRewards(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (struct { - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getStashedLockupRewards", arg0, arg1) - - outstruct := new(struct { - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.LockupExtraReward = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.LockupBaseReward = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.UnlockedReward = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// GetStashedLockupRewards is a free data retrieval call binding the contract method 0xb810e411. -// -// Solidity: function getStashedLockupRewards(address , uint256 ) view returns(uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractSession) GetStashedLockupRewards(arg0 common.Address, arg1 *big.Int) (struct { - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int -}, error) { - return _Contract.Contract.GetStashedLockupRewards(&_Contract.CallOpts, arg0, arg1) -} - -// GetStashedLockupRewards is a free data retrieval call binding the contract method 0xb810e411. -// -// Solidity: function getStashedLockupRewards(address , uint256 ) view returns(uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractCallerSession) GetStashedLockupRewards(arg0 common.Address, arg1 *big.Int) (struct { - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int -}, error) { - return _Contract.Contract.GetStashedLockupRewards(&_Contract.CallOpts, arg0, arg1) -} - -// GetUnlockedStake is a free data retrieval call binding the contract method 0x12622d0e. -// -// Solidity: function getUnlockedStake(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractCaller) GetUnlockedStake(opts *bind.CallOpts, delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getUnlockedStake", delegator, toValidatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetUnlockedStake is a free data retrieval call binding the contract method 0x12622d0e. -// -// Solidity: function getUnlockedStake(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractSession) GetUnlockedStake(delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetUnlockedStake(&_Contract.CallOpts, delegator, toValidatorID) -} - -// GetUnlockedStake is a free data retrieval call binding the contract method 0x12622d0e. -// -// Solidity: function getUnlockedStake(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractCallerSession) GetUnlockedStake(delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.GetUnlockedStake(&_Contract.CallOpts, delegator, toValidatorID) -} - -// GetValidator is a free data retrieval call binding the contract method 0xb5d89627. -// -// Solidity: function getValidator(uint256 ) view returns(uint256 status, uint256 deactivatedTime, uint256 deactivatedEpoch, uint256 receivedStake, uint256 createdEpoch, uint256 createdTime, address auth) -func (_Contract *ContractCaller) GetValidator(opts *bind.CallOpts, arg0 *big.Int) (struct { - Status *big.Int - DeactivatedTime *big.Int - DeactivatedEpoch *big.Int - ReceivedStake *big.Int - CreatedEpoch *big.Int - CreatedTime *big.Int - Auth common.Address -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getValidator", arg0) - - outstruct := new(struct { - Status *big.Int - DeactivatedTime *big.Int - DeactivatedEpoch *big.Int - ReceivedStake *big.Int - CreatedEpoch *big.Int - CreatedTime *big.Int - Auth common.Address - }) - if err != nil { - return *outstruct, err - } - - outstruct.Status = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.DeactivatedTime = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.DeactivatedEpoch = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.ReceivedStake = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - outstruct.CreatedEpoch = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) - outstruct.CreatedTime = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) - outstruct.Auth = *abi.ConvertType(out[6], new(common.Address)).(*common.Address) - - return *outstruct, err - -} - -// GetValidator is a free data retrieval call binding the contract method 0xb5d89627. -// -// Solidity: function getValidator(uint256 ) view returns(uint256 status, uint256 deactivatedTime, uint256 deactivatedEpoch, uint256 receivedStake, uint256 createdEpoch, uint256 createdTime, address auth) -func (_Contract *ContractSession) GetValidator(arg0 *big.Int) (struct { - Status *big.Int - DeactivatedTime *big.Int - DeactivatedEpoch *big.Int - ReceivedStake *big.Int - CreatedEpoch *big.Int - CreatedTime *big.Int - Auth common.Address -}, error) { - return _Contract.Contract.GetValidator(&_Contract.CallOpts, arg0) -} - -// GetValidator is a free data retrieval call binding the contract method 0xb5d89627. -// -// Solidity: function getValidator(uint256 ) view returns(uint256 status, uint256 deactivatedTime, uint256 deactivatedEpoch, uint256 receivedStake, uint256 createdEpoch, uint256 createdTime, address auth) -func (_Contract *ContractCallerSession) GetValidator(arg0 *big.Int) (struct { - Status *big.Int - DeactivatedTime *big.Int - DeactivatedEpoch *big.Int - ReceivedStake *big.Int - CreatedEpoch *big.Int - CreatedTime *big.Int - Auth common.Address -}, error) { - return _Contract.Contract.GetValidator(&_Contract.CallOpts, arg0) -} - -// GetValidatorID is a free data retrieval call binding the contract method 0x0135b1db. -// -// Solidity: function getValidatorID(address ) view returns(uint256) -func (_Contract *ContractCaller) GetValidatorID(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getValidatorID", arg0) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetValidatorID is a free data retrieval call binding the contract method 0x0135b1db. -// -// Solidity: function getValidatorID(address ) view returns(uint256) -func (_Contract *ContractSession) GetValidatorID(arg0 common.Address) (*big.Int, error) { - return _Contract.Contract.GetValidatorID(&_Contract.CallOpts, arg0) -} - -// GetValidatorID is a free data retrieval call binding the contract method 0x0135b1db. -// -// Solidity: function getValidatorID(address ) view returns(uint256) -func (_Contract *ContractCallerSession) GetValidatorID(arg0 common.Address) (*big.Int, error) { - return _Contract.Contract.GetValidatorID(&_Contract.CallOpts, arg0) -} - -// GetValidatorPubkey is a free data retrieval call binding the contract method 0x854873e1. -// -// Solidity: function getValidatorPubkey(uint256 ) view returns(bytes) -func (_Contract *ContractCaller) GetValidatorPubkey(opts *bind.CallOpts, arg0 *big.Int) ([]byte, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getValidatorPubkey", arg0) - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -// GetValidatorPubkey is a free data retrieval call binding the contract method 0x854873e1. -// -// Solidity: function getValidatorPubkey(uint256 ) view returns(bytes) -func (_Contract *ContractSession) GetValidatorPubkey(arg0 *big.Int) ([]byte, error) { - return _Contract.Contract.GetValidatorPubkey(&_Contract.CallOpts, arg0) -} - -// GetValidatorPubkey is a free data retrieval call binding the contract method 0x854873e1. -// -// Solidity: function getValidatorPubkey(uint256 ) view returns(bytes) -func (_Contract *ContractCallerSession) GetValidatorPubkey(arg0 *big.Int) ([]byte, error) { - return _Contract.Contract.GetValidatorPubkey(&_Contract.CallOpts, arg0) -} - -// GetWithdrawalRequest is a free data retrieval call binding the contract method 0x1f270152. -// -// Solidity: function getWithdrawalRequest(address , uint256 , uint256 ) view returns(uint256 epoch, uint256 time, uint256 amount) -func (_Contract *ContractCaller) GetWithdrawalRequest(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int, arg2 *big.Int) (struct { - Epoch *big.Int - Time *big.Int - Amount *big.Int -}, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "getWithdrawalRequest", arg0, arg1, arg2) - - outstruct := new(struct { - Epoch *big.Int - Time *big.Int - Amount *big.Int - }) - if err != nil { - return *outstruct, err - } - - outstruct.Epoch = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.Time = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.Amount = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - - return *outstruct, err - -} - -// GetWithdrawalRequest is a free data retrieval call binding the contract method 0x1f270152. -// -// Solidity: function getWithdrawalRequest(address , uint256 , uint256 ) view returns(uint256 epoch, uint256 time, uint256 amount) -func (_Contract *ContractSession) GetWithdrawalRequest(arg0 common.Address, arg1 *big.Int, arg2 *big.Int) (struct { - Epoch *big.Int - Time *big.Int - Amount *big.Int -}, error) { - return _Contract.Contract.GetWithdrawalRequest(&_Contract.CallOpts, arg0, arg1, arg2) -} - -// GetWithdrawalRequest is a free data retrieval call binding the contract method 0x1f270152. -// -// Solidity: function getWithdrawalRequest(address , uint256 , uint256 ) view returns(uint256 epoch, uint256 time, uint256 amount) -func (_Contract *ContractCallerSession) GetWithdrawalRequest(arg0 common.Address, arg1 *big.Int, arg2 *big.Int) (struct { - Epoch *big.Int - Time *big.Int - Amount *big.Int -}, error) { - return _Contract.Contract.GetWithdrawalRequest(&_Contract.CallOpts, arg0, arg1, arg2) -} - -// IsLockedUp is a free data retrieval call binding the contract method 0xcfdbb7cd. -// -// Solidity: function isLockedUp(address delegator, uint256 toValidatorID) view returns(bool) -func (_Contract *ContractCaller) IsLockedUp(opts *bind.CallOpts, delegator common.Address, toValidatorID *big.Int) (bool, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "isLockedUp", delegator, toValidatorID) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// IsLockedUp is a free data retrieval call binding the contract method 0xcfdbb7cd. -// -// Solidity: function isLockedUp(address delegator, uint256 toValidatorID) view returns(bool) -func (_Contract *ContractSession) IsLockedUp(delegator common.Address, toValidatorID *big.Int) (bool, error) { - return _Contract.Contract.IsLockedUp(&_Contract.CallOpts, delegator, toValidatorID) -} - -// IsLockedUp is a free data retrieval call binding the contract method 0xcfdbb7cd. -// -// Solidity: function isLockedUp(address delegator, uint256 toValidatorID) view returns(bool) -func (_Contract *ContractCallerSession) IsLockedUp(delegator common.Address, toValidatorID *big.Int) (bool, error) { - return _Contract.Contract.IsLockedUp(&_Contract.CallOpts, delegator, toValidatorID) -} - -// IsOwner is a free data retrieval call binding the contract method 0x8f32d59b. -// -// Solidity: function isOwner() view returns(bool) -func (_Contract *ContractCaller) IsOwner(opts *bind.CallOpts) (bool, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "isOwner") - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// IsOwner is a free data retrieval call binding the contract method 0x8f32d59b. -// -// Solidity: function isOwner() view returns(bool) -func (_Contract *ContractSession) IsOwner() (bool, error) { - return _Contract.Contract.IsOwner(&_Contract.CallOpts) -} - -// IsOwner is a free data retrieval call binding the contract method 0x8f32d59b. -// -// Solidity: function isOwner() view returns(bool) -func (_Contract *ContractCallerSession) IsOwner() (bool, error) { - return _Contract.Contract.IsOwner(&_Contract.CallOpts) -} - -// IsSlashed is a free data retrieval call binding the contract method 0xc3de580e. -// -// Solidity: function isSlashed(uint256 validatorID) view returns(bool) -func (_Contract *ContractCaller) IsSlashed(opts *bind.CallOpts, validatorID *big.Int) (bool, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "isSlashed", validatorID) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// IsSlashed is a free data retrieval call binding the contract method 0xc3de580e. -// -// Solidity: function isSlashed(uint256 validatorID) view returns(bool) -func (_Contract *ContractSession) IsSlashed(validatorID *big.Int) (bool, error) { - return _Contract.Contract.IsSlashed(&_Contract.CallOpts, validatorID) -} - -// IsSlashed is a free data retrieval call binding the contract method 0xc3de580e. -// -// Solidity: function isSlashed(uint256 validatorID) view returns(bool) -func (_Contract *ContractCallerSession) IsSlashed(validatorID *big.Int) (bool, error) { - return _Contract.Contract.IsSlashed(&_Contract.CallOpts, validatorID) -} - -// LastValidatorID is a free data retrieval call binding the contract method 0xc7be95de. -// -// Solidity: function lastValidatorID() view returns(uint256) -func (_Contract *ContractCaller) LastValidatorID(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "lastValidatorID") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// LastValidatorID is a free data retrieval call binding the contract method 0xc7be95de. -// -// Solidity: function lastValidatorID() view returns(uint256) -func (_Contract *ContractSession) LastValidatorID() (*big.Int, error) { - return _Contract.Contract.LastValidatorID(&_Contract.CallOpts) -} - -// LastValidatorID is a free data retrieval call binding the contract method 0xc7be95de. -// -// Solidity: function lastValidatorID() view returns(uint256) -func (_Contract *ContractCallerSession) LastValidatorID() (*big.Int, error) { - return _Contract.Contract.LastValidatorID(&_Contract.CallOpts) -} - -// MinGasPrice is a free data retrieval call binding the contract method 0xd96ed505. -// -// Solidity: function minGasPrice() view returns(uint256) -func (_Contract *ContractCaller) MinGasPrice(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "minGasPrice") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// MinGasPrice is a free data retrieval call binding the contract method 0xd96ed505. -// -// Solidity: function minGasPrice() view returns(uint256) -func (_Contract *ContractSession) MinGasPrice() (*big.Int, error) { - return _Contract.Contract.MinGasPrice(&_Contract.CallOpts) -} - -// MinGasPrice is a free data retrieval call binding the contract method 0xd96ed505. -// -// Solidity: function minGasPrice() view returns(uint256) -func (_Contract *ContractCallerSession) MinGasPrice() (*big.Int, error) { - return _Contract.Contract.MinGasPrice(&_Contract.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Contract *ContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Contract *ContractSession) Owner() (common.Address, error) { - return _Contract.Contract.Owner(&_Contract.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Contract *ContractCallerSession) Owner() (common.Address, error) { - return _Contract.Contract.Owner(&_Contract.CallOpts) -} - -// PendingRewards is a free data retrieval call binding the contract method 0x6099ecb2. -// -// Solidity: function pendingRewards(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractCaller) PendingRewards(opts *bind.CallOpts, delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "pendingRewards", delegator, toValidatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// PendingRewards is a free data retrieval call binding the contract method 0x6099ecb2. -// -// Solidity: function pendingRewards(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractSession) PendingRewards(delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.PendingRewards(&_Contract.CallOpts, delegator, toValidatorID) -} - -// PendingRewards is a free data retrieval call binding the contract method 0x6099ecb2. -// -// Solidity: function pendingRewards(address delegator, uint256 toValidatorID) view returns(uint256) -func (_Contract *ContractCallerSession) PendingRewards(delegator common.Address, toValidatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.PendingRewards(&_Contract.CallOpts, delegator, toValidatorID) -} - -// RewardsStash is a free data retrieval call binding the contract method 0x6f498663. -// -// Solidity: function rewardsStash(address delegator, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCaller) RewardsStash(opts *bind.CallOpts, delegator common.Address, validatorID *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "rewardsStash", delegator, validatorID) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// RewardsStash is a free data retrieval call binding the contract method 0x6f498663. -// -// Solidity: function rewardsStash(address delegator, uint256 validatorID) view returns(uint256) -func (_Contract *ContractSession) RewardsStash(delegator common.Address, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.RewardsStash(&_Contract.CallOpts, delegator, validatorID) -} - -// RewardsStash is a free data retrieval call binding the contract method 0x6f498663. -// -// Solidity: function rewardsStash(address delegator, uint256 validatorID) view returns(uint256) -func (_Contract *ContractCallerSession) RewardsStash(delegator common.Address, validatorID *big.Int) (*big.Int, error) { - return _Contract.Contract.RewardsStash(&_Contract.CallOpts, delegator, validatorID) -} - -// SlashingRefundRatio is a free data retrieval call binding the contract method 0xc65ee0e1. -// -// Solidity: function slashingRefundRatio(uint256 ) view returns(uint256) -func (_Contract *ContractCaller) SlashingRefundRatio(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "slashingRefundRatio", arg0) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// SlashingRefundRatio is a free data retrieval call binding the contract method 0xc65ee0e1. -// -// Solidity: function slashingRefundRatio(uint256 ) view returns(uint256) -func (_Contract *ContractSession) SlashingRefundRatio(arg0 *big.Int) (*big.Int, error) { - return _Contract.Contract.SlashingRefundRatio(&_Contract.CallOpts, arg0) -} - -// SlashingRefundRatio is a free data retrieval call binding the contract method 0xc65ee0e1. -// -// Solidity: function slashingRefundRatio(uint256 ) view returns(uint256) -func (_Contract *ContractCallerSession) SlashingRefundRatio(arg0 *big.Int) (*big.Int, error) { - return _Contract.Contract.SlashingRefundRatio(&_Contract.CallOpts, arg0) -} - -// StakeTokenizerAddress is a free data retrieval call binding the contract method 0x0e559d82. -// -// Solidity: function stakeTokenizerAddress() view returns(address) -func (_Contract *ContractCaller) StakeTokenizerAddress(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "stakeTokenizerAddress") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// StakeTokenizerAddress is a free data retrieval call binding the contract method 0x0e559d82. -// -// Solidity: function stakeTokenizerAddress() view returns(address) -func (_Contract *ContractSession) StakeTokenizerAddress() (common.Address, error) { - return _Contract.Contract.StakeTokenizerAddress(&_Contract.CallOpts) -} - -// StakeTokenizerAddress is a free data retrieval call binding the contract method 0x0e559d82. -// -// Solidity: function stakeTokenizerAddress() view returns(address) -func (_Contract *ContractCallerSession) StakeTokenizerAddress() (common.Address, error) { - return _Contract.Contract.StakeTokenizerAddress(&_Contract.CallOpts) -} - -// StashedRewardsUntilEpoch is a free data retrieval call binding the contract method 0xa86a056f. -// -// Solidity: function stashedRewardsUntilEpoch(address , uint256 ) view returns(uint256) -func (_Contract *ContractCaller) StashedRewardsUntilEpoch(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "stashedRewardsUntilEpoch", arg0, arg1) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// StashedRewardsUntilEpoch is a free data retrieval call binding the contract method 0xa86a056f. -// -// Solidity: function stashedRewardsUntilEpoch(address , uint256 ) view returns(uint256) -func (_Contract *ContractSession) StashedRewardsUntilEpoch(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - return _Contract.Contract.StashedRewardsUntilEpoch(&_Contract.CallOpts, arg0, arg1) -} - -// StashedRewardsUntilEpoch is a free data retrieval call binding the contract method 0xa86a056f. -// -// Solidity: function stashedRewardsUntilEpoch(address , uint256 ) view returns(uint256) -func (_Contract *ContractCallerSession) StashedRewardsUntilEpoch(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { - return _Contract.Contract.StashedRewardsUntilEpoch(&_Contract.CallOpts, arg0, arg1) -} - -// TotalActiveStake is a free data retrieval call binding the contract method 0x28f73148. -// -// Solidity: function totalActiveStake() view returns(uint256) -func (_Contract *ContractCaller) TotalActiveStake(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "totalActiveStake") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalActiveStake is a free data retrieval call binding the contract method 0x28f73148. -// -// Solidity: function totalActiveStake() view returns(uint256) -func (_Contract *ContractSession) TotalActiveStake() (*big.Int, error) { - return _Contract.Contract.TotalActiveStake(&_Contract.CallOpts) -} - -// TotalActiveStake is a free data retrieval call binding the contract method 0x28f73148. -// -// Solidity: function totalActiveStake() view returns(uint256) -func (_Contract *ContractCallerSession) TotalActiveStake() (*big.Int, error) { - return _Contract.Contract.TotalActiveStake(&_Contract.CallOpts) -} - -// TotalSlashedStake is a free data retrieval call binding the contract method 0x5fab23a8. -// -// Solidity: function totalSlashedStake() view returns(uint256) -func (_Contract *ContractCaller) TotalSlashedStake(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "totalSlashedStake") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalSlashedStake is a free data retrieval call binding the contract method 0x5fab23a8. -// -// Solidity: function totalSlashedStake() view returns(uint256) -func (_Contract *ContractSession) TotalSlashedStake() (*big.Int, error) { - return _Contract.Contract.TotalSlashedStake(&_Contract.CallOpts) -} - -// TotalSlashedStake is a free data retrieval call binding the contract method 0x5fab23a8. -// -// Solidity: function totalSlashedStake() view returns(uint256) -func (_Contract *ContractCallerSession) TotalSlashedStake() (*big.Int, error) { - return _Contract.Contract.TotalSlashedStake(&_Contract.CallOpts) -} - -// TotalStake is a free data retrieval call binding the contract method 0x8b0e9f3f. -// -// Solidity: function totalStake() view returns(uint256) -func (_Contract *ContractCaller) TotalStake(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "totalStake") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalStake is a free data retrieval call binding the contract method 0x8b0e9f3f. -// -// Solidity: function totalStake() view returns(uint256) -func (_Contract *ContractSession) TotalStake() (*big.Int, error) { - return _Contract.Contract.TotalStake(&_Contract.CallOpts) -} - -// TotalStake is a free data retrieval call binding the contract method 0x8b0e9f3f. -// -// Solidity: function totalStake() view returns(uint256) -func (_Contract *ContractCallerSession) TotalStake() (*big.Int, error) { - return _Contract.Contract.TotalStake(&_Contract.CallOpts) -} - -// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. -// -// Solidity: function totalSupply() view returns(uint256) -func (_Contract *ContractCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "totalSupply") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. -// -// Solidity: function totalSupply() view returns(uint256) -func (_Contract *ContractSession) TotalSupply() (*big.Int, error) { - return _Contract.Contract.TotalSupply(&_Contract.CallOpts) -} - -// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. -// -// Solidity: function totalSupply() view returns(uint256) -func (_Contract *ContractCallerSession) TotalSupply() (*big.Int, error) { - return _Contract.Contract.TotalSupply(&_Contract.CallOpts) -} - -// TreasuryAddress is a free data retrieval call binding the contract method 0xc5f956af. -// -// Solidity: function treasuryAddress() view returns(address) -func (_Contract *ContractCaller) TreasuryAddress(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "treasuryAddress") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// TreasuryAddress is a free data retrieval call binding the contract method 0xc5f956af. -// -// Solidity: function treasuryAddress() view returns(address) -func (_Contract *ContractSession) TreasuryAddress() (common.Address, error) { - return _Contract.Contract.TreasuryAddress(&_Contract.CallOpts) -} - -// TreasuryAddress is a free data retrieval call binding the contract method 0xc5f956af. -// -// Solidity: function treasuryAddress() view returns(address) -func (_Contract *ContractCallerSession) TreasuryAddress() (common.Address, error) { - return _Contract.Contract.TreasuryAddress(&_Contract.CallOpts) -} - -// VoteBookAddress is a free data retrieval call binding the contract method 0x893675c6. -// -// Solidity: function voteBookAddress() view returns(address) -func (_Contract *ContractCaller) VoteBookAddress(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "voteBookAddress") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// VoteBookAddress is a free data retrieval call binding the contract method 0x893675c6. -// -// Solidity: function voteBookAddress() view returns(address) -func (_Contract *ContractSession) VoteBookAddress() (common.Address, error) { - return _Contract.Contract.VoteBookAddress(&_Contract.CallOpts) -} - -// VoteBookAddress is a free data retrieval call binding the contract method 0x893675c6. -// -// Solidity: function voteBookAddress() view returns(address) -func (_Contract *ContractCallerSession) VoteBookAddress() (common.Address, error) { - return _Contract.Contract.VoteBookAddress(&_Contract.CallOpts) -} - -// SyncValidator is a paid mutator transaction binding the contract method 0xcc8343aa. -// -// Solidity: function _syncValidator(uint256 validatorID, bool syncPubkey) returns() -func (_Contract *ContractTransactor) SyncValidator(opts *bind.TransactOpts, validatorID *big.Int, syncPubkey bool) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "_syncValidator", validatorID, syncPubkey) -} - -// SyncValidator is a paid mutator transaction binding the contract method 0xcc8343aa. -// -// Solidity: function _syncValidator(uint256 validatorID, bool syncPubkey) returns() -func (_Contract *ContractSession) SyncValidator(validatorID *big.Int, syncPubkey bool) (*types.Transaction, error) { - return _Contract.Contract.SyncValidator(&_Contract.TransactOpts, validatorID, syncPubkey) -} - -// SyncValidator is a paid mutator transaction binding the contract method 0xcc8343aa. -// -// Solidity: function _syncValidator(uint256 validatorID, bool syncPubkey) returns() -func (_Contract *ContractTransactorSession) SyncValidator(validatorID *big.Int, syncPubkey bool) (*types.Transaction, error) { - return _Contract.Contract.SyncValidator(&_Contract.TransactOpts, validatorID, syncPubkey) -} - -// BurnFTM is a paid mutator transaction binding the contract method 0x90a6c475. -// -// Solidity: function burnFTM(uint256 amount) returns() -func (_Contract *ContractTransactor) BurnFTM(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "burnFTM", amount) -} - -// BurnFTM is a paid mutator transaction binding the contract method 0x90a6c475. -// -// Solidity: function burnFTM(uint256 amount) returns() -func (_Contract *ContractSession) BurnFTM(amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.BurnFTM(&_Contract.TransactOpts, amount) -} - -// BurnFTM is a paid mutator transaction binding the contract method 0x90a6c475. -// -// Solidity: function burnFTM(uint256 amount) returns() -func (_Contract *ContractTransactorSession) BurnFTM(amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.BurnFTM(&_Contract.TransactOpts, amount) -} - -// ClaimRewards is a paid mutator transaction binding the contract method 0x0962ef79. -// -// Solidity: function claimRewards(uint256 toValidatorID) returns() -func (_Contract *ContractTransactor) ClaimRewards(opts *bind.TransactOpts, toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "claimRewards", toValidatorID) -} - -// ClaimRewards is a paid mutator transaction binding the contract method 0x0962ef79. -// -// Solidity: function claimRewards(uint256 toValidatorID) returns() -func (_Contract *ContractSession) ClaimRewards(toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.ClaimRewards(&_Contract.TransactOpts, toValidatorID) -} - -// ClaimRewards is a paid mutator transaction binding the contract method 0x0962ef79. -// -// Solidity: function claimRewards(uint256 toValidatorID) returns() -func (_Contract *ContractTransactorSession) ClaimRewards(toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.ClaimRewards(&_Contract.TransactOpts, toValidatorID) -} - -// CreateValidator is a paid mutator transaction binding the contract method 0xa5a470ad. -// -// Solidity: function createValidator(bytes pubkey) payable returns() -func (_Contract *ContractTransactor) CreateValidator(opts *bind.TransactOpts, pubkey []byte) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "createValidator", pubkey) -} - -// CreateValidator is a paid mutator transaction binding the contract method 0xa5a470ad. -// -// Solidity: function createValidator(bytes pubkey) payable returns() -func (_Contract *ContractSession) CreateValidator(pubkey []byte) (*types.Transaction, error) { - return _Contract.Contract.CreateValidator(&_Contract.TransactOpts, pubkey) -} - -// CreateValidator is a paid mutator transaction binding the contract method 0xa5a470ad. -// -// Solidity: function createValidator(bytes pubkey) payable returns() -func (_Contract *ContractTransactorSession) CreateValidator(pubkey []byte) (*types.Transaction, error) { - return _Contract.Contract.CreateValidator(&_Contract.TransactOpts, pubkey) -} - -// DeactivateValidator is a paid mutator transaction binding the contract method 0x1e702f83. -// -// Solidity: function deactivateValidator(uint256 validatorID, uint256 status) returns() -func (_Contract *ContractTransactor) DeactivateValidator(opts *bind.TransactOpts, validatorID *big.Int, status *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "deactivateValidator", validatorID, status) -} - -// DeactivateValidator is a paid mutator transaction binding the contract method 0x1e702f83. -// -// Solidity: function deactivateValidator(uint256 validatorID, uint256 status) returns() -func (_Contract *ContractSession) DeactivateValidator(validatorID *big.Int, status *big.Int) (*types.Transaction, error) { - return _Contract.Contract.DeactivateValidator(&_Contract.TransactOpts, validatorID, status) -} - -// DeactivateValidator is a paid mutator transaction binding the contract method 0x1e702f83. -// -// Solidity: function deactivateValidator(uint256 validatorID, uint256 status) returns() -func (_Contract *ContractTransactorSession) DeactivateValidator(validatorID *big.Int, status *big.Int) (*types.Transaction, error) { - return _Contract.Contract.DeactivateValidator(&_Contract.TransactOpts, validatorID, status) -} - -// Delegate is a paid mutator transaction binding the contract method 0x9fa6dd35. -// -// Solidity: function delegate(uint256 toValidatorID) payable returns() -func (_Contract *ContractTransactor) Delegate(opts *bind.TransactOpts, toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "delegate", toValidatorID) -} - -// Delegate is a paid mutator transaction binding the contract method 0x9fa6dd35. -// -// Solidity: function delegate(uint256 toValidatorID) payable returns() -func (_Contract *ContractSession) Delegate(toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Delegate(&_Contract.TransactOpts, toValidatorID) -} - -// Delegate is a paid mutator transaction binding the contract method 0x9fa6dd35. -// -// Solidity: function delegate(uint256 toValidatorID) payable returns() -func (_Contract *ContractTransactorSession) Delegate(toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Delegate(&_Contract.TransactOpts, toValidatorID) -} - -// LiquidateSFTM is a paid mutator transaction binding the contract method 0x3a488397. -// -// Solidity: function liquidateSFTM(address delegator, uint256 toValidatorID, uint256 amount) returns() -func (_Contract *ContractTransactor) LiquidateSFTM(opts *bind.TransactOpts, delegator common.Address, toValidatorID *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "liquidateSFTM", delegator, toValidatorID, amount) -} - -// LiquidateSFTM is a paid mutator transaction binding the contract method 0x3a488397. -// -// Solidity: function liquidateSFTM(address delegator, uint256 toValidatorID, uint256 amount) returns() -func (_Contract *ContractSession) LiquidateSFTM(delegator common.Address, toValidatorID *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.LiquidateSFTM(&_Contract.TransactOpts, delegator, toValidatorID, amount) -} - -// LiquidateSFTM is a paid mutator transaction binding the contract method 0x3a488397. -// -// Solidity: function liquidateSFTM(address delegator, uint256 toValidatorID, uint256 amount) returns() -func (_Contract *ContractTransactorSession) LiquidateSFTM(delegator common.Address, toValidatorID *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.LiquidateSFTM(&_Contract.TransactOpts, delegator, toValidatorID, amount) -} - -// LockStake is a paid mutator transaction binding the contract method 0xde67f215. -// -// Solidity: function lockStake(uint256 toValidatorID, uint256 lockupDuration, uint256 amount) returns() -func (_Contract *ContractTransactor) LockStake(opts *bind.TransactOpts, toValidatorID *big.Int, lockupDuration *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "lockStake", toValidatorID, lockupDuration, amount) -} - -// LockStake is a paid mutator transaction binding the contract method 0xde67f215. -// -// Solidity: function lockStake(uint256 toValidatorID, uint256 lockupDuration, uint256 amount) returns() -func (_Contract *ContractSession) LockStake(toValidatorID *big.Int, lockupDuration *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.LockStake(&_Contract.TransactOpts, toValidatorID, lockupDuration, amount) -} - -// LockStake is a paid mutator transaction binding the contract method 0xde67f215. -// -// Solidity: function lockStake(uint256 toValidatorID, uint256 lockupDuration, uint256 amount) returns() -func (_Contract *ContractTransactorSession) LockStake(toValidatorID *big.Int, lockupDuration *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.LockStake(&_Contract.TransactOpts, toValidatorID, lockupDuration, amount) -} - -// RecountVotes is a paid mutator transaction binding the contract method 0x20c0849d. -// -// Solidity: function recountVotes(address delegator, address validatorAuth, bool strict, uint256 gas) returns() -func (_Contract *ContractTransactor) RecountVotes(opts *bind.TransactOpts, delegator common.Address, validatorAuth common.Address, strict bool, gas *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "recountVotes", delegator, validatorAuth, strict, gas) -} - -// RecountVotes is a paid mutator transaction binding the contract method 0x20c0849d. -// -// Solidity: function recountVotes(address delegator, address validatorAuth, bool strict, uint256 gas) returns() -func (_Contract *ContractSession) RecountVotes(delegator common.Address, validatorAuth common.Address, strict bool, gas *big.Int) (*types.Transaction, error) { - return _Contract.Contract.RecountVotes(&_Contract.TransactOpts, delegator, validatorAuth, strict, gas) -} - -// RecountVotes is a paid mutator transaction binding the contract method 0x20c0849d. -// -// Solidity: function recountVotes(address delegator, address validatorAuth, bool strict, uint256 gas) returns() -func (_Contract *ContractTransactorSession) RecountVotes(delegator common.Address, validatorAuth common.Address, strict bool, gas *big.Int) (*types.Transaction, error) { - return _Contract.Contract.RecountVotes(&_Contract.TransactOpts, delegator, validatorAuth, strict, gas) -} - -// RelockStake is a paid mutator transaction binding the contract method 0xbd14d907. -// -// Solidity: function relockStake(uint256 toValidatorID, uint256 lockupDuration, uint256 amount) returns() -func (_Contract *ContractTransactor) RelockStake(opts *bind.TransactOpts, toValidatorID *big.Int, lockupDuration *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "relockStake", toValidatorID, lockupDuration, amount) -} - -// RelockStake is a paid mutator transaction binding the contract method 0xbd14d907. -// -// Solidity: function relockStake(uint256 toValidatorID, uint256 lockupDuration, uint256 amount) returns() -func (_Contract *ContractSession) RelockStake(toValidatorID *big.Int, lockupDuration *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.RelockStake(&_Contract.TransactOpts, toValidatorID, lockupDuration, amount) -} - -// RelockStake is a paid mutator transaction binding the contract method 0xbd14d907. -// -// Solidity: function relockStake(uint256 toValidatorID, uint256 lockupDuration, uint256 amount) returns() -func (_Contract *ContractTransactorSession) RelockStake(toValidatorID *big.Int, lockupDuration *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.RelockStake(&_Contract.TransactOpts, toValidatorID, lockupDuration, amount) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Contract *ContractTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Contract *ContractSession) RenounceOwnership() (*types.Transaction, error) { - return _Contract.Contract.RenounceOwnership(&_Contract.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Contract *ContractTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _Contract.Contract.RenounceOwnership(&_Contract.TransactOpts) -} - -// RestakeRewards is a paid mutator transaction binding the contract method 0x08c36874. -// -// Solidity: function restakeRewards(uint256 toValidatorID) returns() -func (_Contract *ContractTransactor) RestakeRewards(opts *bind.TransactOpts, toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "restakeRewards", toValidatorID) -} - -// RestakeRewards is a paid mutator transaction binding the contract method 0x08c36874. -// -// Solidity: function restakeRewards(uint256 toValidatorID) returns() -func (_Contract *ContractSession) RestakeRewards(toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.RestakeRewards(&_Contract.TransactOpts, toValidatorID) -} - -// RestakeRewards is a paid mutator transaction binding the contract method 0x08c36874. -// -// Solidity: function restakeRewards(uint256 toValidatorID) returns() -func (_Contract *ContractTransactorSession) RestakeRewards(toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.RestakeRewards(&_Contract.TransactOpts, toValidatorID) -} - -// SetGenesisDelegation is a paid mutator transaction binding the contract method 0x18f628d4. -// -// Solidity: function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake, uint256 lockedStake, uint256 lockupFromEpoch, uint256 lockupEndTime, uint256 lockupDuration, uint256 earlyUnlockPenalty, uint256 rewards) returns() -func (_Contract *ContractTransactor) SetGenesisDelegation(opts *bind.TransactOpts, delegator common.Address, toValidatorID *big.Int, stake *big.Int, lockedStake *big.Int, lockupFromEpoch *big.Int, lockupEndTime *big.Int, lockupDuration *big.Int, earlyUnlockPenalty *big.Int, rewards *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "setGenesisDelegation", delegator, toValidatorID, stake, lockedStake, lockupFromEpoch, lockupEndTime, lockupDuration, earlyUnlockPenalty, rewards) -} - -// SetGenesisDelegation is a paid mutator transaction binding the contract method 0x18f628d4. -// -// Solidity: function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake, uint256 lockedStake, uint256 lockupFromEpoch, uint256 lockupEndTime, uint256 lockupDuration, uint256 earlyUnlockPenalty, uint256 rewards) returns() -func (_Contract *ContractSession) SetGenesisDelegation(delegator common.Address, toValidatorID *big.Int, stake *big.Int, lockedStake *big.Int, lockupFromEpoch *big.Int, lockupEndTime *big.Int, lockupDuration *big.Int, earlyUnlockPenalty *big.Int, rewards *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisDelegation(&_Contract.TransactOpts, delegator, toValidatorID, stake, lockedStake, lockupFromEpoch, lockupEndTime, lockupDuration, earlyUnlockPenalty, rewards) -} - -// SetGenesisDelegation is a paid mutator transaction binding the contract method 0x18f628d4. -// -// Solidity: function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake, uint256 lockedStake, uint256 lockupFromEpoch, uint256 lockupEndTime, uint256 lockupDuration, uint256 earlyUnlockPenalty, uint256 rewards) returns() -func (_Contract *ContractTransactorSession) SetGenesisDelegation(delegator common.Address, toValidatorID *big.Int, stake *big.Int, lockedStake *big.Int, lockupFromEpoch *big.Int, lockupEndTime *big.Int, lockupDuration *big.Int, earlyUnlockPenalty *big.Int, rewards *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisDelegation(&_Contract.TransactOpts, delegator, toValidatorID, stake, lockedStake, lockupFromEpoch, lockupEndTime, lockupDuration, earlyUnlockPenalty, rewards) -} - -// SetGenesisValidator is a paid mutator transaction binding the contract method 0x4feb92f3. -// -// Solidity: function setGenesisValidator(address auth, uint256 validatorID, bytes pubkey, uint256 status, uint256 createdEpoch, uint256 createdTime, uint256 deactivatedEpoch, uint256 deactivatedTime) returns() -func (_Contract *ContractTransactor) SetGenesisValidator(opts *bind.TransactOpts, auth common.Address, validatorID *big.Int, pubkey []byte, status *big.Int, createdEpoch *big.Int, createdTime *big.Int, deactivatedEpoch *big.Int, deactivatedTime *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "setGenesisValidator", auth, validatorID, pubkey, status, createdEpoch, createdTime, deactivatedEpoch, deactivatedTime) -} - -// SetGenesisValidator is a paid mutator transaction binding the contract method 0x4feb92f3. -// -// Solidity: function setGenesisValidator(address auth, uint256 validatorID, bytes pubkey, uint256 status, uint256 createdEpoch, uint256 createdTime, uint256 deactivatedEpoch, uint256 deactivatedTime) returns() -func (_Contract *ContractSession) SetGenesisValidator(auth common.Address, validatorID *big.Int, pubkey []byte, status *big.Int, createdEpoch *big.Int, createdTime *big.Int, deactivatedEpoch *big.Int, deactivatedTime *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisValidator(&_Contract.TransactOpts, auth, validatorID, pubkey, status, createdEpoch, createdTime, deactivatedEpoch, deactivatedTime) -} - -// SetGenesisValidator is a paid mutator transaction binding the contract method 0x4feb92f3. -// -// Solidity: function setGenesisValidator(address auth, uint256 validatorID, bytes pubkey, uint256 status, uint256 createdEpoch, uint256 createdTime, uint256 deactivatedEpoch, uint256 deactivatedTime) returns() -func (_Contract *ContractTransactorSession) SetGenesisValidator(auth common.Address, validatorID *big.Int, pubkey []byte, status *big.Int, createdEpoch *big.Int, createdTime *big.Int, deactivatedEpoch *big.Int, deactivatedTime *big.Int) (*types.Transaction, error) { - return _Contract.Contract.SetGenesisValidator(&_Contract.TransactOpts, auth, validatorID, pubkey, status, createdEpoch, createdTime, deactivatedEpoch, deactivatedTime) -} - -// StashRewards is a paid mutator transaction binding the contract method 0x8cddb015. -// -// Solidity: function stashRewards(address delegator, uint256 toValidatorID) returns() -func (_Contract *ContractTransactor) StashRewards(opts *bind.TransactOpts, delegator common.Address, toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "stashRewards", delegator, toValidatorID) -} - -// StashRewards is a paid mutator transaction binding the contract method 0x8cddb015. -// -// Solidity: function stashRewards(address delegator, uint256 toValidatorID) returns() -func (_Contract *ContractSession) StashRewards(delegator common.Address, toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.StashRewards(&_Contract.TransactOpts, delegator, toValidatorID) -} - -// StashRewards is a paid mutator transaction binding the contract method 0x8cddb015. -// -// Solidity: function stashRewards(address delegator, uint256 toValidatorID) returns() -func (_Contract *ContractTransactorSession) StashRewards(delegator common.Address, toValidatorID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.StashRewards(&_Contract.TransactOpts, delegator, toValidatorID) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Contract *ContractTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferOwnership", newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Contract *ContractSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Contract.Contract.TransferOwnership(&_Contract.TransactOpts, newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Contract *ContractTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Contract.Contract.TransferOwnership(&_Contract.TransactOpts, newOwner) -} - -// Undelegate is a paid mutator transaction binding the contract method 0x4f864df4. -// -// Solidity: function undelegate(uint256 toValidatorID, uint256 wrID, uint256 amount) returns() -func (_Contract *ContractTransactor) Undelegate(opts *bind.TransactOpts, toValidatorID *big.Int, wrID *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "undelegate", toValidatorID, wrID, amount) -} - -// Undelegate is a paid mutator transaction binding the contract method 0x4f864df4. -// -// Solidity: function undelegate(uint256 toValidatorID, uint256 wrID, uint256 amount) returns() -func (_Contract *ContractSession) Undelegate(toValidatorID *big.Int, wrID *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Undelegate(&_Contract.TransactOpts, toValidatorID, wrID, amount) -} - -// Undelegate is a paid mutator transaction binding the contract method 0x4f864df4. -// -// Solidity: function undelegate(uint256 toValidatorID, uint256 wrID, uint256 amount) returns() -func (_Contract *ContractTransactorSession) Undelegate(toValidatorID *big.Int, wrID *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Undelegate(&_Contract.TransactOpts, toValidatorID, wrID, amount) -} - -// UnlockStake is a paid mutator transaction binding the contract method 0x1d3ac42c. -// -// Solidity: function unlockStake(uint256 toValidatorID, uint256 amount) returns(uint256) -func (_Contract *ContractTransactor) UnlockStake(opts *bind.TransactOpts, toValidatorID *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "unlockStake", toValidatorID, amount) -} - -// UnlockStake is a paid mutator transaction binding the contract method 0x1d3ac42c. -// -// Solidity: function unlockStake(uint256 toValidatorID, uint256 amount) returns(uint256) -func (_Contract *ContractSession) UnlockStake(toValidatorID *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UnlockStake(&_Contract.TransactOpts, toValidatorID, amount) -} - -// UnlockStake is a paid mutator transaction binding the contract method 0x1d3ac42c. -// -// Solidity: function unlockStake(uint256 toValidatorID, uint256 amount) returns(uint256) -func (_Contract *ContractTransactorSession) UnlockStake(toValidatorID *big.Int, amount *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UnlockStake(&_Contract.TransactOpts, toValidatorID, amount) -} - -// UpdateSFTMFinalizer is a paid mutator transaction binding the contract method 0x2ce71960. -// -// Solidity: function updateSFTMFinalizer(address v) returns() -func (_Contract *ContractTransactor) UpdateSFTMFinalizer(opts *bind.TransactOpts, v common.Address) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateSFTMFinalizer", v) -} - -// UpdateSFTMFinalizer is a paid mutator transaction binding the contract method 0x2ce71960. -// -// Solidity: function updateSFTMFinalizer(address v) returns() -func (_Contract *ContractSession) UpdateSFTMFinalizer(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateSFTMFinalizer(&_Contract.TransactOpts, v) -} - -// UpdateSFTMFinalizer is a paid mutator transaction binding the contract method 0x2ce71960. -// -// Solidity: function updateSFTMFinalizer(address v) returns() -func (_Contract *ContractTransactorSession) UpdateSFTMFinalizer(v common.Address) (*types.Transaction, error) { - return _Contract.Contract.UpdateSFTMFinalizer(&_Contract.TransactOpts, v) -} - -// UpdateSlashingRefundRatio is a paid mutator transaction binding the contract method 0x4f7c4efb. -// -// Solidity: function updateSlashingRefundRatio(uint256 validatorID, uint256 refundRatio) returns() -func (_Contract *ContractTransactor) UpdateSlashingRefundRatio(opts *bind.TransactOpts, validatorID *big.Int, refundRatio *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "updateSlashingRefundRatio", validatorID, refundRatio) -} - -// UpdateSlashingRefundRatio is a paid mutator transaction binding the contract method 0x4f7c4efb. -// -// Solidity: function updateSlashingRefundRatio(uint256 validatorID, uint256 refundRatio) returns() -func (_Contract *ContractSession) UpdateSlashingRefundRatio(validatorID *big.Int, refundRatio *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateSlashingRefundRatio(&_Contract.TransactOpts, validatorID, refundRatio) -} - -// UpdateSlashingRefundRatio is a paid mutator transaction binding the contract method 0x4f7c4efb. -// -// Solidity: function updateSlashingRefundRatio(uint256 validatorID, uint256 refundRatio) returns() -func (_Contract *ContractTransactorSession) UpdateSlashingRefundRatio(validatorID *big.Int, refundRatio *big.Int) (*types.Transaction, error) { - return _Contract.Contract.UpdateSlashingRefundRatio(&_Contract.TransactOpts, validatorID, refundRatio) -} - -// Withdraw is a paid mutator transaction binding the contract method 0x441a3e70. -// -// Solidity: function withdraw(uint256 toValidatorID, uint256 wrID) returns() -func (_Contract *ContractTransactor) Withdraw(opts *bind.TransactOpts, toValidatorID *big.Int, wrID *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "withdraw", toValidatorID, wrID) -} - -// Withdraw is a paid mutator transaction binding the contract method 0x441a3e70. -// -// Solidity: function withdraw(uint256 toValidatorID, uint256 wrID) returns() -func (_Contract *ContractSession) Withdraw(toValidatorID *big.Int, wrID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Withdraw(&_Contract.TransactOpts, toValidatorID, wrID) -} - -// Withdraw is a paid mutator transaction binding the contract method 0x441a3e70. -// -// Solidity: function withdraw(uint256 toValidatorID, uint256 wrID) returns() -func (_Contract *ContractTransactorSession) Withdraw(toValidatorID *big.Int, wrID *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Withdraw(&_Contract.TransactOpts, toValidatorID, wrID) -} - -// ContractBurntFTMIterator is returned from FilterBurntFTM and is used to iterate over the raw logs and unpacked data for BurntFTM events raised by the Contract contract. -type ContractBurntFTMIterator struct { - Event *ContractBurntFTM // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractBurntFTMIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractBurntFTM) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractBurntFTM) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractBurntFTMIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractBurntFTMIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractBurntFTM represents a BurntFTM event raised by the Contract contract. -type ContractBurntFTM struct { - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterBurntFTM is a free log retrieval operation binding the contract event 0x8918bd6046d08b314e457977f29562c5d76a7030d79b1edba66e8a5da0b77ae8. -// -// Solidity: event BurntFTM(uint256 amount) -func (_Contract *ContractFilterer) FilterBurntFTM(opts *bind.FilterOpts) (*ContractBurntFTMIterator, error) { - - logs, sub, err := _Contract.contract.FilterLogs(opts, "BurntFTM") - if err != nil { - return nil, err - } - return &ContractBurntFTMIterator{contract: _Contract.contract, event: "BurntFTM", logs: logs, sub: sub}, nil -} - -// WatchBurntFTM is a free log subscription operation binding the contract event 0x8918bd6046d08b314e457977f29562c5d76a7030d79b1edba66e8a5da0b77ae8. -// -// Solidity: event BurntFTM(uint256 amount) -func (_Contract *ContractFilterer) WatchBurntFTM(opts *bind.WatchOpts, sink chan<- *ContractBurntFTM) (event.Subscription, error) { - - logs, sub, err := _Contract.contract.WatchLogs(opts, "BurntFTM") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractBurntFTM) - if err := _Contract.contract.UnpackLog(event, "BurntFTM", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseBurntFTM is a log parse operation binding the contract event 0x8918bd6046d08b314e457977f29562c5d76a7030d79b1edba66e8a5da0b77ae8. -// -// Solidity: event BurntFTM(uint256 amount) -func (_Contract *ContractFilterer) ParseBurntFTM(log types.Log) (*ContractBurntFTM, error) { - event := new(ContractBurntFTM) - if err := _Contract.contract.UnpackLog(event, "BurntFTM", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractChangedValidatorStatusIterator is returned from FilterChangedValidatorStatus and is used to iterate over the raw logs and unpacked data for ChangedValidatorStatus events raised by the Contract contract. -type ContractChangedValidatorStatusIterator struct { - Event *ContractChangedValidatorStatus // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractChangedValidatorStatusIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractChangedValidatorStatus) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractChangedValidatorStatus) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractChangedValidatorStatusIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractChangedValidatorStatusIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractChangedValidatorStatus represents a ChangedValidatorStatus event raised by the Contract contract. -type ContractChangedValidatorStatus struct { - ValidatorID *big.Int - Status *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterChangedValidatorStatus is a free log retrieval operation binding the contract event 0xcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e. -// -// Solidity: event ChangedValidatorStatus(uint256 indexed validatorID, uint256 status) -func (_Contract *ContractFilterer) FilterChangedValidatorStatus(opts *bind.FilterOpts, validatorID []*big.Int) (*ContractChangedValidatorStatusIterator, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "ChangedValidatorStatus", validatorIDRule) - if err != nil { - return nil, err - } - return &ContractChangedValidatorStatusIterator{contract: _Contract.contract, event: "ChangedValidatorStatus", logs: logs, sub: sub}, nil -} - -// WatchChangedValidatorStatus is a free log subscription operation binding the contract event 0xcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e. -// -// Solidity: event ChangedValidatorStatus(uint256 indexed validatorID, uint256 status) -func (_Contract *ContractFilterer) WatchChangedValidatorStatus(opts *bind.WatchOpts, sink chan<- *ContractChangedValidatorStatus, validatorID []*big.Int) (event.Subscription, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "ChangedValidatorStatus", validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractChangedValidatorStatus) - if err := _Contract.contract.UnpackLog(event, "ChangedValidatorStatus", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseChangedValidatorStatus is a log parse operation binding the contract event 0xcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e. -// -// Solidity: event ChangedValidatorStatus(uint256 indexed validatorID, uint256 status) -func (_Contract *ContractFilterer) ParseChangedValidatorStatus(log types.Log) (*ContractChangedValidatorStatus, error) { - event := new(ContractChangedValidatorStatus) - if err := _Contract.contract.UnpackLog(event, "ChangedValidatorStatus", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractClaimedRewardsIterator is returned from FilterClaimedRewards and is used to iterate over the raw logs and unpacked data for ClaimedRewards events raised by the Contract contract. -type ContractClaimedRewardsIterator struct { - Event *ContractClaimedRewards // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractClaimedRewardsIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractClaimedRewards) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractClaimedRewards) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractClaimedRewardsIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractClaimedRewardsIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractClaimedRewards represents a ClaimedRewards event raised by the Contract contract. -type ContractClaimedRewards struct { - Delegator common.Address - ToValidatorID *big.Int - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterClaimedRewards is a free log retrieval operation binding the contract event 0xc1d8eb6e444b89fb8ff0991c19311c070df704ccb009e210d1462d5b2410bf45. -// -// Solidity: event ClaimedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractFilterer) FilterClaimedRewards(opts *bind.FilterOpts, delegator []common.Address, toValidatorID []*big.Int) (*ContractClaimedRewardsIterator, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "ClaimedRewards", delegatorRule, toValidatorIDRule) - if err != nil { - return nil, err - } - return &ContractClaimedRewardsIterator{contract: _Contract.contract, event: "ClaimedRewards", logs: logs, sub: sub}, nil -} - -// WatchClaimedRewards is a free log subscription operation binding the contract event 0xc1d8eb6e444b89fb8ff0991c19311c070df704ccb009e210d1462d5b2410bf45. -// -// Solidity: event ClaimedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractFilterer) WatchClaimedRewards(opts *bind.WatchOpts, sink chan<- *ContractClaimedRewards, delegator []common.Address, toValidatorID []*big.Int) (event.Subscription, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "ClaimedRewards", delegatorRule, toValidatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractClaimedRewards) - if err := _Contract.contract.UnpackLog(event, "ClaimedRewards", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseClaimedRewards is a log parse operation binding the contract event 0xc1d8eb6e444b89fb8ff0991c19311c070df704ccb009e210d1462d5b2410bf45. -// -// Solidity: event ClaimedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractFilterer) ParseClaimedRewards(log types.Log) (*ContractClaimedRewards, error) { - event := new(ContractClaimedRewards) - if err := _Contract.contract.UnpackLog(event, "ClaimedRewards", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractCreatedValidatorIterator is returned from FilterCreatedValidator and is used to iterate over the raw logs and unpacked data for CreatedValidator events raised by the Contract contract. -type ContractCreatedValidatorIterator struct { - Event *ContractCreatedValidator // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractCreatedValidatorIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractCreatedValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractCreatedValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractCreatedValidatorIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractCreatedValidatorIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractCreatedValidator represents a CreatedValidator event raised by the Contract contract. -type ContractCreatedValidator struct { - ValidatorID *big.Int - Auth common.Address - CreatedEpoch *big.Int - CreatedTime *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterCreatedValidator is a free log retrieval operation binding the contract event 0x49bca1ed2666922f9f1690c26a569e1299c2a715fe57647d77e81adfabbf25bf. -// -// Solidity: event CreatedValidator(uint256 indexed validatorID, address indexed auth, uint256 createdEpoch, uint256 createdTime) -func (_Contract *ContractFilterer) FilterCreatedValidator(opts *bind.FilterOpts, validatorID []*big.Int, auth []common.Address) (*ContractCreatedValidatorIterator, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - var authRule []interface{} - for _, authItem := range auth { - authRule = append(authRule, authItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "CreatedValidator", validatorIDRule, authRule) - if err != nil { - return nil, err - } - return &ContractCreatedValidatorIterator{contract: _Contract.contract, event: "CreatedValidator", logs: logs, sub: sub}, nil -} - -// WatchCreatedValidator is a free log subscription operation binding the contract event 0x49bca1ed2666922f9f1690c26a569e1299c2a715fe57647d77e81adfabbf25bf. -// -// Solidity: event CreatedValidator(uint256 indexed validatorID, address indexed auth, uint256 createdEpoch, uint256 createdTime) -func (_Contract *ContractFilterer) WatchCreatedValidator(opts *bind.WatchOpts, sink chan<- *ContractCreatedValidator, validatorID []*big.Int, auth []common.Address) (event.Subscription, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - var authRule []interface{} - for _, authItem := range auth { - authRule = append(authRule, authItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "CreatedValidator", validatorIDRule, authRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractCreatedValidator) - if err := _Contract.contract.UnpackLog(event, "CreatedValidator", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseCreatedValidator is a log parse operation binding the contract event 0x49bca1ed2666922f9f1690c26a569e1299c2a715fe57647d77e81adfabbf25bf. -// -// Solidity: event CreatedValidator(uint256 indexed validatorID, address indexed auth, uint256 createdEpoch, uint256 createdTime) -func (_Contract *ContractFilterer) ParseCreatedValidator(log types.Log) (*ContractCreatedValidator, error) { - event := new(ContractCreatedValidator) - if err := _Contract.contract.UnpackLog(event, "CreatedValidator", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractDeactivatedValidatorIterator is returned from FilterDeactivatedValidator and is used to iterate over the raw logs and unpacked data for DeactivatedValidator events raised by the Contract contract. -type ContractDeactivatedValidatorIterator struct { - Event *ContractDeactivatedValidator // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractDeactivatedValidatorIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractDeactivatedValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractDeactivatedValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractDeactivatedValidatorIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractDeactivatedValidatorIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractDeactivatedValidator represents a DeactivatedValidator event raised by the Contract contract. -type ContractDeactivatedValidator struct { - ValidatorID *big.Int - DeactivatedEpoch *big.Int - DeactivatedTime *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDeactivatedValidator is a free log retrieval operation binding the contract event 0xac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e47. -// -// Solidity: event DeactivatedValidator(uint256 indexed validatorID, uint256 deactivatedEpoch, uint256 deactivatedTime) -func (_Contract *ContractFilterer) FilterDeactivatedValidator(opts *bind.FilterOpts, validatorID []*big.Int) (*ContractDeactivatedValidatorIterator, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "DeactivatedValidator", validatorIDRule) - if err != nil { - return nil, err - } - return &ContractDeactivatedValidatorIterator{contract: _Contract.contract, event: "DeactivatedValidator", logs: logs, sub: sub}, nil -} - -// WatchDeactivatedValidator is a free log subscription operation binding the contract event 0xac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e47. -// -// Solidity: event DeactivatedValidator(uint256 indexed validatorID, uint256 deactivatedEpoch, uint256 deactivatedTime) -func (_Contract *ContractFilterer) WatchDeactivatedValidator(opts *bind.WatchOpts, sink chan<- *ContractDeactivatedValidator, validatorID []*big.Int) (event.Subscription, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "DeactivatedValidator", validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractDeactivatedValidator) - if err := _Contract.contract.UnpackLog(event, "DeactivatedValidator", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseDeactivatedValidator is a log parse operation binding the contract event 0xac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e47. -// -// Solidity: event DeactivatedValidator(uint256 indexed validatorID, uint256 deactivatedEpoch, uint256 deactivatedTime) -func (_Contract *ContractFilterer) ParseDeactivatedValidator(log types.Log) (*ContractDeactivatedValidator, error) { - event := new(ContractDeactivatedValidator) - if err := _Contract.contract.UnpackLog(event, "DeactivatedValidator", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractDelegatedIterator is returned from FilterDelegated and is used to iterate over the raw logs and unpacked data for Delegated events raised by the Contract contract. -type ContractDelegatedIterator struct { - Event *ContractDelegated // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractDelegatedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractDelegated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractDelegated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractDelegatedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractDelegatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractDelegated represents a Delegated event raised by the Contract contract. -type ContractDelegated struct { - Delegator common.Address - ToValidatorID *big.Int - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDelegated is a free log retrieval operation binding the contract event 0x9a8f44850296624dadfd9c246d17e47171d35727a181bd090aa14bbbe00238bb. -// -// Solidity: event Delegated(address indexed delegator, uint256 indexed toValidatorID, uint256 amount) -func (_Contract *ContractFilterer) FilterDelegated(opts *bind.FilterOpts, delegator []common.Address, toValidatorID []*big.Int) (*ContractDelegatedIterator, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "Delegated", delegatorRule, toValidatorIDRule) - if err != nil { - return nil, err - } - return &ContractDelegatedIterator{contract: _Contract.contract, event: "Delegated", logs: logs, sub: sub}, nil -} - -// WatchDelegated is a free log subscription operation binding the contract event 0x9a8f44850296624dadfd9c246d17e47171d35727a181bd090aa14bbbe00238bb. -// -// Solidity: event Delegated(address indexed delegator, uint256 indexed toValidatorID, uint256 amount) -func (_Contract *ContractFilterer) WatchDelegated(opts *bind.WatchOpts, sink chan<- *ContractDelegated, delegator []common.Address, toValidatorID []*big.Int) (event.Subscription, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "Delegated", delegatorRule, toValidatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractDelegated) - if err := _Contract.contract.UnpackLog(event, "Delegated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseDelegated is a log parse operation binding the contract event 0x9a8f44850296624dadfd9c246d17e47171d35727a181bd090aa14bbbe00238bb. -// -// Solidity: event Delegated(address indexed delegator, uint256 indexed toValidatorID, uint256 amount) -func (_Contract *ContractFilterer) ParseDelegated(log types.Log) (*ContractDelegated, error) { - event := new(ContractDelegated) - if err := _Contract.contract.UnpackLog(event, "Delegated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractLockedUpStakeIterator is returned from FilterLockedUpStake and is used to iterate over the raw logs and unpacked data for LockedUpStake events raised by the Contract contract. -type ContractLockedUpStakeIterator struct { - Event *ContractLockedUpStake // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractLockedUpStakeIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractLockedUpStake) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractLockedUpStake) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractLockedUpStakeIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractLockedUpStakeIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractLockedUpStake represents a LockedUpStake event raised by the Contract contract. -type ContractLockedUpStake struct { - Delegator common.Address - ValidatorID *big.Int - Duration *big.Int - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterLockedUpStake is a free log retrieval operation binding the contract event 0x138940e95abffcd789b497bf6188bba3afa5fbd22fb5c42c2f6018d1bf0f4e78. -// -// Solidity: event LockedUpStake(address indexed delegator, uint256 indexed validatorID, uint256 duration, uint256 amount) -func (_Contract *ContractFilterer) FilterLockedUpStake(opts *bind.FilterOpts, delegator []common.Address, validatorID []*big.Int) (*ContractLockedUpStakeIterator, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "LockedUpStake", delegatorRule, validatorIDRule) - if err != nil { - return nil, err - } - return &ContractLockedUpStakeIterator{contract: _Contract.contract, event: "LockedUpStake", logs: logs, sub: sub}, nil -} - -// WatchLockedUpStake is a free log subscription operation binding the contract event 0x138940e95abffcd789b497bf6188bba3afa5fbd22fb5c42c2f6018d1bf0f4e78. -// -// Solidity: event LockedUpStake(address indexed delegator, uint256 indexed validatorID, uint256 duration, uint256 amount) -func (_Contract *ContractFilterer) WatchLockedUpStake(opts *bind.WatchOpts, sink chan<- *ContractLockedUpStake, delegator []common.Address, validatorID []*big.Int) (event.Subscription, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "LockedUpStake", delegatorRule, validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractLockedUpStake) - if err := _Contract.contract.UnpackLog(event, "LockedUpStake", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseLockedUpStake is a log parse operation binding the contract event 0x138940e95abffcd789b497bf6188bba3afa5fbd22fb5c42c2f6018d1bf0f4e78. -// -// Solidity: event LockedUpStake(address indexed delegator, uint256 indexed validatorID, uint256 duration, uint256 amount) -func (_Contract *ContractFilterer) ParseLockedUpStake(log types.Log) (*ContractLockedUpStake, error) { - event := new(ContractLockedUpStake) - if err := _Contract.contract.UnpackLog(event, "LockedUpStake", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Contract contract. -type ContractOwnershipTransferredIterator struct { - Event *ContractOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractOwnershipTransferredIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractOwnershipTransferred represents a OwnershipTransferred event raised by the Contract contract. -type ContractOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Contract *ContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ContractOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return &ContractOwnershipTransferredIterator{contract: _Contract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Contract *ContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ContractOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractOwnershipTransferred) - if err := _Contract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Contract *ContractFilterer) ParseOwnershipTransferred(log types.Log) (*ContractOwnershipTransferred, error) { - event := new(ContractOwnershipTransferred) - if err := _Contract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractRefundedSlashedLegacyDelegationIterator is returned from FilterRefundedSlashedLegacyDelegation and is used to iterate over the raw logs and unpacked data for RefundedSlashedLegacyDelegation events raised by the Contract contract. -type ContractRefundedSlashedLegacyDelegationIterator struct { - Event *ContractRefundedSlashedLegacyDelegation // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractRefundedSlashedLegacyDelegationIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractRefundedSlashedLegacyDelegation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractRefundedSlashedLegacyDelegation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractRefundedSlashedLegacyDelegationIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractRefundedSlashedLegacyDelegationIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractRefundedSlashedLegacyDelegation represents a RefundedSlashedLegacyDelegation event raised by the Contract contract. -type ContractRefundedSlashedLegacyDelegation struct { - Delegator common.Address - ValidatorID *big.Int - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterRefundedSlashedLegacyDelegation is a free log retrieval operation binding the contract event 0x172fdfaf5222519d28d2794b7617be033f46d954f9b6c3896e7d2611ff444252. -// -// Solidity: event RefundedSlashedLegacyDelegation(address indexed delegator, uint256 indexed validatorID, uint256 amount) -func (_Contract *ContractFilterer) FilterRefundedSlashedLegacyDelegation(opts *bind.FilterOpts, delegator []common.Address, validatorID []*big.Int) (*ContractRefundedSlashedLegacyDelegationIterator, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "RefundedSlashedLegacyDelegation", delegatorRule, validatorIDRule) - if err != nil { - return nil, err - } - return &ContractRefundedSlashedLegacyDelegationIterator{contract: _Contract.contract, event: "RefundedSlashedLegacyDelegation", logs: logs, sub: sub}, nil -} - -// WatchRefundedSlashedLegacyDelegation is a free log subscription operation binding the contract event 0x172fdfaf5222519d28d2794b7617be033f46d954f9b6c3896e7d2611ff444252. -// -// Solidity: event RefundedSlashedLegacyDelegation(address indexed delegator, uint256 indexed validatorID, uint256 amount) -func (_Contract *ContractFilterer) WatchRefundedSlashedLegacyDelegation(opts *bind.WatchOpts, sink chan<- *ContractRefundedSlashedLegacyDelegation, delegator []common.Address, validatorID []*big.Int) (event.Subscription, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "RefundedSlashedLegacyDelegation", delegatorRule, validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractRefundedSlashedLegacyDelegation) - if err := _Contract.contract.UnpackLog(event, "RefundedSlashedLegacyDelegation", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseRefundedSlashedLegacyDelegation is a log parse operation binding the contract event 0x172fdfaf5222519d28d2794b7617be033f46d954f9b6c3896e7d2611ff444252. -// -// Solidity: event RefundedSlashedLegacyDelegation(address indexed delegator, uint256 indexed validatorID, uint256 amount) -func (_Contract *ContractFilterer) ParseRefundedSlashedLegacyDelegation(log types.Log) (*ContractRefundedSlashedLegacyDelegation, error) { - event := new(ContractRefundedSlashedLegacyDelegation) - if err := _Contract.contract.UnpackLog(event, "RefundedSlashedLegacyDelegation", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractRestakedRewardsIterator is returned from FilterRestakedRewards and is used to iterate over the raw logs and unpacked data for RestakedRewards events raised by the Contract contract. -type ContractRestakedRewardsIterator struct { - Event *ContractRestakedRewards // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractRestakedRewardsIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractRestakedRewards) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractRestakedRewards) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractRestakedRewardsIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractRestakedRewardsIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractRestakedRewards represents a RestakedRewards event raised by the Contract contract. -type ContractRestakedRewards struct { - Delegator common.Address - ToValidatorID *big.Int - LockupExtraReward *big.Int - LockupBaseReward *big.Int - UnlockedReward *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterRestakedRewards is a free log retrieval operation binding the contract event 0x4119153d17a36f9597d40e3ab4148d03261a439dddbec4e91799ab7159608e26. -// -// Solidity: event RestakedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractFilterer) FilterRestakedRewards(opts *bind.FilterOpts, delegator []common.Address, toValidatorID []*big.Int) (*ContractRestakedRewardsIterator, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "RestakedRewards", delegatorRule, toValidatorIDRule) - if err != nil { - return nil, err - } - return &ContractRestakedRewardsIterator{contract: _Contract.contract, event: "RestakedRewards", logs: logs, sub: sub}, nil -} - -// WatchRestakedRewards is a free log subscription operation binding the contract event 0x4119153d17a36f9597d40e3ab4148d03261a439dddbec4e91799ab7159608e26. -// -// Solidity: event RestakedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractFilterer) WatchRestakedRewards(opts *bind.WatchOpts, sink chan<- *ContractRestakedRewards, delegator []common.Address, toValidatorID []*big.Int) (event.Subscription, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "RestakedRewards", delegatorRule, toValidatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractRestakedRewards) - if err := _Contract.contract.UnpackLog(event, "RestakedRewards", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseRestakedRewards is a log parse operation binding the contract event 0x4119153d17a36f9597d40e3ab4148d03261a439dddbec4e91799ab7159608e26. -// -// Solidity: event RestakedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 lockupExtraReward, uint256 lockupBaseReward, uint256 unlockedReward) -func (_Contract *ContractFilterer) ParseRestakedRewards(log types.Log) (*ContractRestakedRewards, error) { - event := new(ContractRestakedRewards) - if err := _Contract.contract.UnpackLog(event, "RestakedRewards", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUndelegatedIterator is returned from FilterUndelegated and is used to iterate over the raw logs and unpacked data for Undelegated events raised by the Contract contract. -type ContractUndelegatedIterator struct { - Event *ContractUndelegated // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUndelegatedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUndelegated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUndelegated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUndelegatedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUndelegatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUndelegated represents a Undelegated event raised by the Contract contract. -type ContractUndelegated struct { - Delegator common.Address - ToValidatorID *big.Int - WrID *big.Int - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUndelegated is a free log retrieval operation binding the contract event 0xd3bb4e423fbea695d16b982f9f682dc5f35152e5411646a8a5a79a6b02ba8d57. -// -// Solidity: event Undelegated(address indexed delegator, uint256 indexed toValidatorID, uint256 indexed wrID, uint256 amount) -func (_Contract *ContractFilterer) FilterUndelegated(opts *bind.FilterOpts, delegator []common.Address, toValidatorID []*big.Int, wrID []*big.Int) (*ContractUndelegatedIterator, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - var wrIDRule []interface{} - for _, wrIDItem := range wrID { - wrIDRule = append(wrIDRule, wrIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "Undelegated", delegatorRule, toValidatorIDRule, wrIDRule) - if err != nil { - return nil, err - } - return &ContractUndelegatedIterator{contract: _Contract.contract, event: "Undelegated", logs: logs, sub: sub}, nil -} - -// WatchUndelegated is a free log subscription operation binding the contract event 0xd3bb4e423fbea695d16b982f9f682dc5f35152e5411646a8a5a79a6b02ba8d57. -// -// Solidity: event Undelegated(address indexed delegator, uint256 indexed toValidatorID, uint256 indexed wrID, uint256 amount) -func (_Contract *ContractFilterer) WatchUndelegated(opts *bind.WatchOpts, sink chan<- *ContractUndelegated, delegator []common.Address, toValidatorID []*big.Int, wrID []*big.Int) (event.Subscription, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - var wrIDRule []interface{} - for _, wrIDItem := range wrID { - wrIDRule = append(wrIDRule, wrIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "Undelegated", delegatorRule, toValidatorIDRule, wrIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUndelegated) - if err := _Contract.contract.UnpackLog(event, "Undelegated", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUndelegated is a log parse operation binding the contract event 0xd3bb4e423fbea695d16b982f9f682dc5f35152e5411646a8a5a79a6b02ba8d57. -// -// Solidity: event Undelegated(address indexed delegator, uint256 indexed toValidatorID, uint256 indexed wrID, uint256 amount) -func (_Contract *ContractFilterer) ParseUndelegated(log types.Log) (*ContractUndelegated, error) { - event := new(ContractUndelegated) - if err := _Contract.contract.UnpackLog(event, "Undelegated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUnlockedStakeIterator is returned from FilterUnlockedStake and is used to iterate over the raw logs and unpacked data for UnlockedStake events raised by the Contract contract. -type ContractUnlockedStakeIterator struct { - Event *ContractUnlockedStake // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUnlockedStakeIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUnlockedStake) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUnlockedStake) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUnlockedStakeIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUnlockedStakeIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUnlockedStake represents a UnlockedStake event raised by the Contract contract. -type ContractUnlockedStake struct { - Delegator common.Address - ValidatorID *big.Int - Amount *big.Int - Penalty *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUnlockedStake is a free log retrieval operation binding the contract event 0xef6c0c14fe9aa51af36acd791464dec3badbde668b63189b47bfa4e25be9b2b9. -// -// Solidity: event UnlockedStake(address indexed delegator, uint256 indexed validatorID, uint256 amount, uint256 penalty) -func (_Contract *ContractFilterer) FilterUnlockedStake(opts *bind.FilterOpts, delegator []common.Address, validatorID []*big.Int) (*ContractUnlockedStakeIterator, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "UnlockedStake", delegatorRule, validatorIDRule) - if err != nil { - return nil, err - } - return &ContractUnlockedStakeIterator{contract: _Contract.contract, event: "UnlockedStake", logs: logs, sub: sub}, nil -} - -// WatchUnlockedStake is a free log subscription operation binding the contract event 0xef6c0c14fe9aa51af36acd791464dec3badbde668b63189b47bfa4e25be9b2b9. -// -// Solidity: event UnlockedStake(address indexed delegator, uint256 indexed validatorID, uint256 amount, uint256 penalty) -func (_Contract *ContractFilterer) WatchUnlockedStake(opts *bind.WatchOpts, sink chan<- *ContractUnlockedStake, delegator []common.Address, validatorID []*big.Int) (event.Subscription, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "UnlockedStake", delegatorRule, validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUnlockedStake) - if err := _Contract.contract.UnpackLog(event, "UnlockedStake", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUnlockedStake is a log parse operation binding the contract event 0xef6c0c14fe9aa51af36acd791464dec3badbde668b63189b47bfa4e25be9b2b9. -// -// Solidity: event UnlockedStake(address indexed delegator, uint256 indexed validatorID, uint256 amount, uint256 penalty) -func (_Contract *ContractFilterer) ParseUnlockedStake(log types.Log) (*ContractUnlockedStake, error) { - event := new(ContractUnlockedStake) - if err := _Contract.contract.UnpackLog(event, "UnlockedStake", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractUpdatedSlashingRefundRatioIterator is returned from FilterUpdatedSlashingRefundRatio and is used to iterate over the raw logs and unpacked data for UpdatedSlashingRefundRatio events raised by the Contract contract. -type ContractUpdatedSlashingRefundRatioIterator struct { - Event *ContractUpdatedSlashingRefundRatio // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractUpdatedSlashingRefundRatioIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractUpdatedSlashingRefundRatio) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractUpdatedSlashingRefundRatio) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractUpdatedSlashingRefundRatioIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractUpdatedSlashingRefundRatioIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractUpdatedSlashingRefundRatio represents a UpdatedSlashingRefundRatio event raised by the Contract contract. -type ContractUpdatedSlashingRefundRatio struct { - ValidatorID *big.Int - RefundRatio *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdatedSlashingRefundRatio is a free log retrieval operation binding the contract event 0x047575f43f09a7a093d94ec483064acfc61b7e25c0de28017da442abf99cb917. -// -// Solidity: event UpdatedSlashingRefundRatio(uint256 indexed validatorID, uint256 refundRatio) -func (_Contract *ContractFilterer) FilterUpdatedSlashingRefundRatio(opts *bind.FilterOpts, validatorID []*big.Int) (*ContractUpdatedSlashingRefundRatioIterator, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "UpdatedSlashingRefundRatio", validatorIDRule) - if err != nil { - return nil, err - } - return &ContractUpdatedSlashingRefundRatioIterator{contract: _Contract.contract, event: "UpdatedSlashingRefundRatio", logs: logs, sub: sub}, nil -} - -// WatchUpdatedSlashingRefundRatio is a free log subscription operation binding the contract event 0x047575f43f09a7a093d94ec483064acfc61b7e25c0de28017da442abf99cb917. -// -// Solidity: event UpdatedSlashingRefundRatio(uint256 indexed validatorID, uint256 refundRatio) -func (_Contract *ContractFilterer) WatchUpdatedSlashingRefundRatio(opts *bind.WatchOpts, sink chan<- *ContractUpdatedSlashingRefundRatio, validatorID []*big.Int) (event.Subscription, error) { - - var validatorIDRule []interface{} - for _, validatorIDItem := range validatorID { - validatorIDRule = append(validatorIDRule, validatorIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "UpdatedSlashingRefundRatio", validatorIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractUpdatedSlashingRefundRatio) - if err := _Contract.contract.UnpackLog(event, "UpdatedSlashingRefundRatio", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdatedSlashingRefundRatio is a log parse operation binding the contract event 0x047575f43f09a7a093d94ec483064acfc61b7e25c0de28017da442abf99cb917. -// -// Solidity: event UpdatedSlashingRefundRatio(uint256 indexed validatorID, uint256 refundRatio) -func (_Contract *ContractFilterer) ParseUpdatedSlashingRefundRatio(log types.Log) (*ContractUpdatedSlashingRefundRatio, error) { - event := new(ContractUpdatedSlashingRefundRatio) - if err := _Contract.contract.UnpackLog(event, "UpdatedSlashingRefundRatio", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ContractWithdrawnIterator is returned from FilterWithdrawn and is used to iterate over the raw logs and unpacked data for Withdrawn events raised by the Contract contract. -type ContractWithdrawnIterator struct { - Event *ContractWithdrawn // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ContractWithdrawnIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ContractWithdrawn) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ContractWithdrawn) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractWithdrawnIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ContractWithdrawnIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ContractWithdrawn represents a Withdrawn event raised by the Contract contract. -type ContractWithdrawn struct { - Delegator common.Address - ToValidatorID *big.Int - WrID *big.Int - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterWithdrawn is a free log retrieval operation binding the contract event 0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21. -// -// Solidity: event Withdrawn(address indexed delegator, uint256 indexed toValidatorID, uint256 indexed wrID, uint256 amount) -func (_Contract *ContractFilterer) FilterWithdrawn(opts *bind.FilterOpts, delegator []common.Address, toValidatorID []*big.Int, wrID []*big.Int) (*ContractWithdrawnIterator, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - var wrIDRule []interface{} - for _, wrIDItem := range wrID { - wrIDRule = append(wrIDRule, wrIDItem) - } - - logs, sub, err := _Contract.contract.FilterLogs(opts, "Withdrawn", delegatorRule, toValidatorIDRule, wrIDRule) - if err != nil { - return nil, err - } - return &ContractWithdrawnIterator{contract: _Contract.contract, event: "Withdrawn", logs: logs, sub: sub}, nil -} - -// WatchWithdrawn is a free log subscription operation binding the contract event 0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21. -// -// Solidity: event Withdrawn(address indexed delegator, uint256 indexed toValidatorID, uint256 indexed wrID, uint256 amount) -func (_Contract *ContractFilterer) WatchWithdrawn(opts *bind.WatchOpts, sink chan<- *ContractWithdrawn, delegator []common.Address, toValidatorID []*big.Int, wrID []*big.Int) (event.Subscription, error) { - - var delegatorRule []interface{} - for _, delegatorItem := range delegator { - delegatorRule = append(delegatorRule, delegatorItem) - } - var toValidatorIDRule []interface{} - for _, toValidatorIDItem := range toValidatorID { - toValidatorIDRule = append(toValidatorIDRule, toValidatorIDItem) - } - var wrIDRule []interface{} - for _, wrIDItem := range wrID { - wrIDRule = append(wrIDRule, wrIDItem) - } - - logs, sub, err := _Contract.contract.WatchLogs(opts, "Withdrawn", delegatorRule, toValidatorIDRule, wrIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ContractWithdrawn) - if err := _Contract.contract.UnpackLog(event, "Withdrawn", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseWithdrawn is a log parse operation binding the contract event 0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21. -// -// Solidity: event Withdrawn(address indexed delegator, uint256 indexed toValidatorID, uint256 indexed wrID, uint256 amount) -func (_Contract *ContractFilterer) ParseWithdrawn(log types.Log) (*ContractWithdrawn, error) { - event := new(ContractWithdrawn) - if err := _Contract.contract.UnpackLog(event, "Withdrawn", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -var ContractBinRuntime = "0x6080604052600436106103815760003560e01c8063854873e1116101d1578063b88a37e211610102578063cfd47663116100a0578063de67f2151161006f578063de67f21514610f3a578063df00c92214610f70578063e261641a14610fa0578063f2fde38b14610fd057610381565b8063cfd4766314610e83578063cfdbb7cd14610ebc578063d96ed50514610ef5578063dc31e1af14610f0a57610381565b8063c5f956af116100dc578063c5f956af14610dfd578063c65ee0e114610e12578063c7be95de14610e3c578063cc8343aa14610e5157610381565b8063b88a37e214610d23578063bd14d90714610d9d578063c3de580e14610dd357610381565b806396c7ee461161016f578063a5a470ad11610149578063a5a470ad14610bd6578063a86a056f14610c46578063b5d8962714610c7f578063b810e41114610cea57610381565b806396c7ee4614610b2a5780639fa6dd3514610b89578063a198d22914610ba657610381565b80638cddb015116101ab5780638cddb01514610a895780638da5cb5b14610ac25780638f32d59b14610ad757806390a6c47514610b0057610381565b8063854873e1146109c0578063893675c614610a5f5780638b0e9f3f14610a7457610381565b80633a488397116102b65780635fab23a8116102545780636f498663116102235780636f49866314610948578063715018a61461098157806376671808146109965780637cacb1d6146109ab57610381565b80635fab23a8146108915780636099ecb2146108a657806361e53fcc146108df578063670322f81461090f57610381565b80634f864df4116102905780634f864df4146107565780634feb92f31461078c5780635601fe011461083757806358f95b801461086157610381565b80633a488397146106b7578063441a3e70146106f65780634f7c4efb1461072657610381565b80631d3ac42c1161032357806320c0849d116102fd57806320c0849d146105c257806328f731481461060d5780632ce719601461062257806339b80c001461065557610381565b80631d3ac42c146105055780631e702f83146105355780631f2701521461056557610381565b80630e559d821161035f5780630e559d821461042157806312622d0e1461045257806318160ddd1461048b57806318f628d4146104a057610381565b80630135b1db1461038657806308c36874146103cb5780630962ef79146103f7575b600080fd5b34801561039257600080fd5b506103b9600480360360208110156103a957600080fd5b50356001600160a01b0316611003565b60408051918252519081900360200190f35b3480156103d757600080fd5b506103f5600480360360208110156103ee57600080fd5b5035611015565b005b34801561040357600080fd5b506103f56004803603602081101561041a57600080fd5b50356110e1565b34801561042d57600080fd5b5061043661122c565b604080516001600160a01b039092168252519081900360200190f35b34801561045e57600080fd5b506103b96004803603604081101561047557600080fd5b506001600160a01b03813516906020013561123b565b34801561049757600080fd5b506103b96112c4565b3480156104ac57600080fd5b506103f560048036036101208110156104c457600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e08101359061010001356112ca565b34801561051157600080fd5b506103b96004803603604081101561052857600080fd5b508035906020013561142c565b34801561054157600080fd5b506103f56004803603604081101561055857600080fd5b5080359060200135611656565b34801561057157600080fd5b506105a46004803603606081101561058857600080fd5b506001600160a01b03813516906020810135906040013561172f565b60408051938452602084019290925282820152519081900360600190f35b3480156105ce57600080fd5b506103f5600480360360808110156105e557600080fd5b506001600160a01b038135811691602081013590911690604081013515159060600135611761565b34801561061957600080fd5b506103b96118fe565b34801561062e57600080fd5b506103f56004803603602081101561064557600080fd5b50356001600160a01b0316611904565b34801561066157600080fd5b5061067f6004803603602081101561067857600080fd5b5035611997565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b3480156106c357600080fd5b506103f5600480360360608110156106da57600080fd5b506001600160a01b0381351690602081013590604001356119d9565b34801561070257600080fd5b506103f56004803603604081101561071957600080fd5b5080359060200135611d8a565b34801561073257600080fd5b506103f56004803603604081101561074957600080fd5b508035906020013561229a565b34801561076257600080fd5b506103f56004803603606081101561077957600080fd5b50803590602081013590604001356123de565b34801561079857600080fd5b506103f560048036036101008110156107b057600080fd5b6001600160a01b03823516916020810135918101906060810160408201356401000000008111156107e057600080fd5b8201836020820111156107f257600080fd5b8035906020019184600183028401116401000000008311171561081457600080fd5b919350915080359060208101359060408101359060608101359060800135612679565b34801561084357600080fd5b506103b96004803603602081101561085a57600080fd5b503561271f565b34801561086d57600080fd5b506103b96004803603604081101561088457600080fd5b5080359060200135612755565b34801561089d57600080fd5b506103b9612772565b3480156108b257600080fd5b506103b9600480360360408110156108c957600080fd5b506001600160a01b038135169060200135612778565b3480156108eb57600080fd5b506103b96004803603604081101561090257600080fd5b50803590602001356127b6565b34801561091b57600080fd5b506103b96004803603604081101561093257600080fd5b506001600160a01b0381351690602001356127d7565b34801561095457600080fd5b506103b96004803603604081101561096b57600080fd5b506001600160a01b038135169060200135612818565b34801561098d57600080fd5b506103f5612882565b3480156109a257600080fd5b506103b961293d565b3480156109b757600080fd5b506103b9612947565b3480156109cc57600080fd5b506109ea600480360360208110156109e357600080fd5b503561294d565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610a24578181015183820152602001610a0c565b50505050905090810190601f168015610a515780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610a6b57600080fd5b50610436612a06565b348015610a8057600080fd5b506103b9612a15565b348015610a9557600080fd5b506103f560048036036040811015610aac57600080fd5b506001600160a01b038135169060200135612a1b565b348015610ace57600080fd5b50610436612a7a565b348015610ae357600080fd5b50610aec612a89565b604080519115158252519081900360200190f35b348015610b0c57600080fd5b506103f560048036036020811015610b2357600080fd5b5035612a9a565b348015610b3657600080fd5b50610b6360048036036040811015610b4d57600080fd5b506001600160a01b038135169060200135612aff565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6103f560048036036020811015610b9f57600080fd5b5035612b31565b348015610bb257600080fd5b506103b960048036036040811015610bc957600080fd5b5080359060200135612b3c565b6103f560048036036020811015610bec57600080fd5b810190602081018135640100000000811115610c0757600080fd5b820183602082011115610c1957600080fd5b80359060200191846001830284011164010000000083111715610c3b57600080fd5b509092509050612b5d565b348015610c5257600080fd5b506103b960048036036040811015610c6957600080fd5b506001600160a01b038135169060200135612cca565b348015610c8b57600080fd5b50610ca960048036036020811015610ca257600080fd5b5035612ce7565b604080519788526020880196909652868601949094526060860192909252608085015260a08401526001600160a01b031660c0830152519081900360e00190f35b348015610cf657600080fd5b506105a460048036036040811015610d0d57600080fd5b506001600160a01b038135169060200135612d2d565b348015610d2f57600080fd5b50610d4d60048036036020811015610d4657600080fd5b5035612d59565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610d89578181015183820152602001610d71565b505050509050019250505060405180910390f35b348015610da957600080fd5b506103f560048036036060811015610dc057600080fd5b5080359060208101359060400135612dbe565b348015610ddf57600080fd5b50610aec60048036036020811015610df657600080fd5b5035612dd1565b348015610e0957600080fd5b50610436612de8565b348015610e1e57600080fd5b506103b960048036036020811015610e3557600080fd5b5035612df7565b348015610e4857600080fd5b506103b9612e09565b348015610e5d57600080fd5b506103f560048036036040811015610e7457600080fd5b50803590602001351515612e0f565b348015610e8f57600080fd5b506103b960048036036040811015610ea657600080fd5b506001600160a01b038135169060200135613047565b348015610ec857600080fd5b50610aec60048036036040811015610edf57600080fd5b506001600160a01b038135169060200135613064565b348015610f0157600080fd5b506103b96130fa565b348015610f1657600080fd5b506103b960048036036040811015610f2d57600080fd5b5080359060200135613100565b348015610f4657600080fd5b506103f560048036036060811015610f5d57600080fd5b5080359060208101359060400135613121565b348015610f7c57600080fd5b506103b960048036036040811015610f9357600080fd5b50803590602001356131dc565b348015610fac57600080fd5b506103b960048036036040811015610fc357600080fd5b50803590602001356131fd565b348015610fdc57600080fd5b506103f560048036036020811015610ff357600080fd5b50356001600160a01b031661321e565b60696020526000908152604090205481565b3361101e615024565b6110288284613280565b602081015181519192506000916110449163ffffffff6133e016565b905061106783856110628560400151856133e090919063ffffffff16565b61343a565b6001600160a01b0383166000818152607360209081526040808320888452825291829020805485019055845185820151868401518451928352928201528083019190915290518692917f4119153d17a36f9597d40e3ab4148d03261a439dddbec4e91799ab7159608e26919081900360600190a350505050565b336110ea615024565b6110f48284613280565b90506000826001600160a01b03166111318360400151611125856020015186600001516133e090919063ffffffff16565b9063ffffffff6133e016565b604051600081818185875af1925050503d806000811461116d576040519150601f19603f3d011682016040523d82523d6000602084013e611172565b606091505b50509050806111c8576040805162461bcd60e51b815260206004820152601260248201527f4661696c656420746f2073656e642046544d0000000000000000000000000000604482015290519081900360640190fd5b83836001600160a01b03167fc1d8eb6e444b89fb8ff0991c19311c070df704ccb009e210d1462d5b2410bf4584600001518560200151866040015160405180848152602001838152602001828152602001935050505060405180910390a350505050565b607b546001600160a01b031681565b60006112478383613064565b61127557506001600160a01b03821660009081526072602090815260408083208484529091529020546112be565b6001600160a01b0383166000818152607360209081526040808320868452825280832054938352607282528083208684529091529020546112bb9163ffffffff61354616565b90505b92915050565b60765481565b6112d333613588565b61130e5760405162461bcd60e51b81526004018080602001828103825260298152602001806151046029913960400191505060405180910390fd5b61131b898989600061359c565b6001600160a01b0389166000908152606f602090815260408083208b8452909152902060020181905561134d87613734565b851561142157868611156113925760405162461bcd60e51b815260040180806020018281038252602c8152602001806151c0602c913960400191505060405180910390fd5b6001600160a01b03891660008181526073602090815260408083208c845282528083208a8155600181018a90556002810189905560038101889055848452607483528184208d855283529281902086905580518781529182018a9052805192938c9390927f138940e95abffcd789b497bf6188bba3afa5fbd22fb5c42c2f6018d1bf0f4e7892908290030190a3505b505050505050505050565b33600081815260736020908152604080832086845290915281209091908361149b576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b6114a58286613064565b6114f6576040805162461bcd60e51b815260206004820152600d60248201527f6e6f74206c6f636b656420757000000000000000000000000000000000000000604482015290519081900360640190fd5b805484111561154c576040805162461bcd60e51b815260206004820152601760248201527f6e6f7420656e6f756768206c6f636b6564207374616b65000000000000000000604482015290519081900360640190fd5b61155682866137d2565b6115a7576040805162461bcd60e51b815260206004820152601860248201527f6f75747374616e64696e67207346544d2062616c616e63650000000000000000604482015290519081900360640190fd5b6115b1828661388d565b5060006115c48387878560000154613a58565b905081600301546363401ec501826002015410156115e0575060005b815485900382558015611603576115fa8387836001613b89565b61160381613d8f565b85836001600160a01b03167fef6c0c14fe9aa51af36acd791464dec3badbde668b63189b47bfa4e25be9b2b98784604051808381526020018281526020019250505060405180910390a395945050505050565b61165f33613588565b61169a5760405162461bcd60e51b81526004018080602001828103825260298152602001806151046029913960400191505060405180910390fd5b806116ec576040805162461bcd60e51b815260206004820152600c60248201527f77726f6e67207374617475730000000000000000000000000000000000000000604482015290519081900360640190fd5b6116f68282613df9565b611701826000612e0f565b6000828152606860205260408120600601546001600160a01b03169061172a9082908190613f23565b505050565b607160209081526000938452604080852082529284528284209052825290208054600182015460029092015490919083565b608254604080516001600160a01b03878116602483015286811660448084019190915283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f4a7702bb000000000000000000000000000000000000000000000000000000001781529251825160009592909216938693928291908083835b6020831061183057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016117f3565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d8060008114611893576040519150601f19603f3d011682016040523d82523d6000602084013e611898565b606091505b5050905080806118a6575082155b6118f7576040805162461bcd60e51b815260206004820152601b60248201527f676f7620766f746573207265636f756e74696e67206661696c65640000000000604482015290519081900360640190fd5b5050505050565b606d5481565b61190c612a89565b61195d576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b608380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b607760205280600052604060002060009150905080600701549080600801549080600901549080600a01549080600b01549080600c01549080600d0154905087565b6083546001600160a01b03163314611a38576040805162461bcd60e51b815260206004820152601260248201527f6e6f74207346544d2066696e616c697a65720000000000000000000000000000604482015290519081900360640190fd5b611a42838361388d565b5060008111611a98576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b607b54604080517f63d2bde50000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0386811660248301526044820186905260648201859052915191909216916363d2bde591608480830192600092919082900301818387803b158015611b1357600080fd5b505af1158015611b27573d6000803e3d6000fd5b505050506001600160a01b0383166000908152607260209081526040808320858452909152902054811115611ba3576040805162461bcd60e51b815260206004820152601060248201527f6e6f7420656e6f756768207374616b6500000000000000000000000000000000604482015290519081900360640190fd5b6000611baf848461123b565b905080821015611c3e576001600160a01b038416600090815260736020908152604080832086845290915290208054611bf09083850363ffffffff61354616565b815560408051838503815260006020820152815186926001600160a01b038916927fef6c0c14fe9aa51af36acd791464dec3badbde668b63189b47bfa4e25be9b2b9929081900390910190a3505b611c4b8484846001613b89565b611c56836000612e0f565b64ffffffffff83856001600160a01b03167fd3bb4e423fbea695d16b982f9f682dc5f35152e5411646a8a5a79a6b02ba8d57856040518082815260200191505060405180910390a4604051600090339084908381818185875af1925050503d8060008114611ce0576040519150601f19603f3d011682016040523d82523d6000602084013e611ce5565b606091505b5050905080611d3b576040805162461bcd60e51b815260206004820152601260248201527f4661696c656420746f2073656e642046544d0000000000000000000000000000604482015290519081900360640190fd5b64ffffffffff84866001600160a01b03167f75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21866040518082815260200191505060405180910390a45050505050565b33611d93615024565b506001600160a01b038116600090815260716020908152604080832086845282528083208584528252918290208251606081018452815480825260018301549382019390935260029091015492810192909252611e37576040805162461bcd60e51b815260206004820152601560248201527f7265717565737420646f65736e27742065786973740000000000000000000000604482015290519081900360640190fd5b611e4182856137d2565b611e92576040805162461bcd60e51b815260206004820152601860248201527f6f75747374616e64696e67207346544d2062616c616e63650000000000000000604482015290519081900360640190fd5b60208082015182516000878152606890935260409092206001015490919015801590611ece575060008681526068602052604090206001015482115b15611eef575050600084815260686020526040902060018101546002909101545b608160009054906101000a90046001600160a01b03166001600160a01b031663b82b84276040518163ffffffff1660e01b815260040160206040518083038186803b158015611f3d57600080fd5b505afa158015611f51573d6000803e3d6000fd5b505050506040513d6020811015611f6757600080fd5b50518201611f736140cd565b1015611fc6576040805162461bcd60e51b815260206004820152601660248201527f6e6f7420656e6f7567682074696d652070617373656400000000000000000000604482015290519081900360640190fd5b608160009054906101000a90046001600160a01b03166001600160a01b031663650acd666040518163ffffffff1660e01b815260040160206040518083038186803b15801561201457600080fd5b505afa158015612028573d6000803e3d6000fd5b505050506040513d602081101561203e57600080fd5b5051810161204a61293d565b101561209d576040805162461bcd60e51b815260206004820152601860248201527f6e6f7420656e6f7567682065706f636873207061737365640000000000000000604482015290519081900360640190fd5b6001600160a01b03841660009081526071602090815260408083208984528252808320888452909152812060020154906120d688612dd1565b905060006120f88383607a60008d8152602001908152602001600020546140d1565b6001600160a01b03881660009081526071602090815260408083208d845282528083208c845290915281208181556001810182905560020155606e805482019055905080831161218f576040805162461bcd60e51b815260206004820152601660248201527f7374616b652069732066756c6c7920736c617368656400000000000000000000604482015290519081900360640190fd5b60006001600160a01b0388166121ab858463ffffffff61354616565b604051600081818185875af1925050503d80600081146121e7576040519150601f19603f3d011682016040523d82523d6000602084013e6121ec565b606091505b5050905080612242576040805162461bcd60e51b815260206004820152601260248201527f4661696c656420746f2073656e642046544d0000000000000000000000000000604482015290519081900360640190fd5b61224b82613d8f565b888a896001600160a01b03167f75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21876040518082815260200191505060405180910390a450505050505050505050565b6122a2612a89565b6122f3576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6122fc82612dd1565b61234d576040805162461bcd60e51b815260206004820152601760248201527f76616c696461746f722069736e277420736c6173686564000000000000000000604482015290519081900360640190fd5b612355614133565b8111156123935760405162461bcd60e51b815260040180806020018281038252602181526020018061514e6021913960400191505060405180910390fd5b6000828152607a60209081526040918290208390558151838152915184927f047575f43f09a7a093d94ec483064acfc61b7e25c0de28017da442abf99cb91792908290030190a25050565b336123e9818561388d565b506000821161243f576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b612449818561123b565b82111561249d576040805162461bcd60e51b815260206004820152601960248201527f6e6f7420656e6f75676820756e6c6f636b6564207374616b6500000000000000604482015290519081900360640190fd5b6124a781856137d2565b6124f8576040805162461bcd60e51b815260206004820152601860248201527f6f75747374616e64696e67207346544d2062616c616e63650000000000000000604482015290519081900360640190fd5b6001600160a01b0381166000908152607160209081526040808320878452825280832086845290915290206002015415612579576040805162461bcd60e51b815260206004820152601360248201527f7772494420616c72656164792065786973747300000000000000000000000000604482015290519081900360640190fd5b6125868185846001613b89565b6001600160a01b0381166000908152607160209081526040808320878452825280832086845290915290206002018290556125bf61293d565b6001600160a01b038216600090815260716020908152604080832088845282528083208784529091529020556125f36140cd565b6001600160a01b03821660009081526071602090815260408083208884528252808320878452909152812060010191909155612630908590612e0f565b8284826001600160a01b03167fd3bb4e423fbea695d16b982f9f682dc5f35152e5411646a8a5a79a6b02ba8d57856040518082815260200191505060405180910390a450505050565b61268233613588565b6126bd5760405162461bcd60e51b81526004018080602001828103825260298152602001806151046029913960400191505060405180910390fd5b612705898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a9150899050888861413f565b606b5488111561142157606b889055505050505050505050565b6000818152606860209081526040808320600601546001600160a01b03168352607282528083208484529091529020545b919050565b600091825260776020908152604080842092845291905290205490565b606e5481565b6000612782615024565b61278c8484614306565b8051602082015160408301519293506127ae926111259163ffffffff6133e016565b949350505050565b60009182526077602090815260408084209284526001909201905290205490565b60006127e38383613064565b6127ef575060006112be565b506001600160a01b03919091166000908152607360209081526040808320938352929052205490565b6000612822615024565b506001600160a01b0383166000908152606f60209081526040808320858452825291829020825160608101845281548082526001830154938201849052600290920154938101849052926127ae929091611125919063ffffffff6133e016565b61288a612a89565b6128db576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6067546001015b90565b60675481565b606a6020908152600091825260409182902080548351601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600186161502019093169290920491820184900484028101840190945280845290918301828280156129fe5780601f106129d3576101008083540402835291602001916129fe565b820191906000526020600020905b8154815290600101906020018083116129e157829003601f168201915b505050505081565b6082546001600160a01b031681565b606c5481565b612a25828261388d565b612a76576040805162461bcd60e51b815260206004820152601060248201527f6e6f7468696e6720746f20737461736800000000000000000000000000000000604482015290519081900360640190fd5b5050565b6033546001600160a01b031690565b6033546001600160a01b0316331490565b612aa2612a89565b612af3576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b612afc81613d8f565b50565b607360209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b612afc33823461343a565b60009182526077602090815260408084209284526005909201905290205490565b608160009054906101000a90046001600160a01b03166001600160a01b031663c5f530af6040518163ffffffff1660e01b815260040160206040518083038186803b158015612bab57600080fd5b505afa158015612bbf573d6000803e3d6000fd5b505050506040513d6020811015612bd557600080fd5b5051341015612c2b576040805162461bcd60e51b815260206004820152601760248201527f696e73756666696369656e742073656c662d7374616b65000000000000000000604482015290519081900360640190fd5b80612c7d576040805162461bcd60e51b815260206004820152600c60248201527f656d707479207075626b65790000000000000000000000000000000000000000604482015290519081900360640190fd5b612cbd3383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061437492505050565b612a7633606b543461343a565b607060209081526000928352604080842090915290825290205481565b606860205260009081526040902080546001820154600283015460038401546004850154600586015460069096015494959394929391929091906001600160a01b031687565b607460209081526000928352604080842090915290825290208054600182015460029092015490919083565b600081815260776020908152604091829020600601805483518184028101840190945280845260609392830182828015612db257602002820191906000526020600020905b815481526020019060010190808311612d9e575b50505050509050919050565b33612dcb8185858561439f565b50505050565b600090815260686020526040902054608016151590565b607f546001600160a01b031681565b607a6020526000908152604090205481565b606b5481565b612e1882614754565b612e69576040805162461bcd60e51b815260206004820152601760248201527f76616c696461746f7220646f65736e2774206578697374000000000000000000604482015290519081900360640190fd5b60008281526068602052604090206003810154905415612e87575060005b606654604080517fa4066fbe000000000000000000000000000000000000000000000000000000008152600481018690526024810184905290516001600160a01b039092169163a4066fbe9160448082019260009290919082900301818387803b158015612ef457600080fd5b505af1158015612f08573d6000803e3d6000fd5b50505050818015612f1857508015155b1561172a576066546000848152606a60205260409081902081517f242a6e3f0000000000000000000000000000000000000000000000000000000081526004810187815260248201938452825460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001831615610100020190911604604483018190526001600160a01b039095169463242a6e3f948994939091606490910190849080156130095780601f10612fde57610100808354040283529160200191613009565b820191906000526020600020905b815481529060010190602001808311612fec57829003601f168201915b50509350505050600060405180830381600087803b15801561302a57600080fd5b505af115801561303e573d6000803e3d6000fd5b50505050505050565b607260209081526000928352604080842090915290825290205481565b6001600160a01b0382166000908152607360209081526040808320848452909152812060020154158015906130bb57506001600160a01b038316600090815260736020908152604080832085845290915290205415155b80156112bb57506001600160a01b03831660009081526073602090815260408083208584529091529020600201546130f16140cd565b11159392505050565b607e5481565b60009182526077602090815260408084209284526003909201905290205490565b3381613174576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b61317e8185613064565b156131d0576040805162461bcd60e51b815260206004820152601160248201527f616c7265616479206c6f636b6564207570000000000000000000000000000000604482015290519081900360640190fd5b612dcb8185858561439f565b60009182526077602090815260408084209284526002909201905290205490565b60009182526077602090815260408084209284526004909201905290205490565b613226612a89565b613277576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b612afc8161476b565b613288615024565b61329283836137d2565b6132e3576040805162461bcd60e51b815260206004820152601860248201527f6f75747374616e64696e67207346544d2062616c616e63650000000000000000604482015290519081900360640190fd5b6132ed838361388d565b50506001600160a01b0382166000908152606f602090815260408083208484528252808320815160608101835281548082526001830154948201859052600290920154928101839052939261334b926111259163ffffffff6133e016565b90508061339f576040805162461bcd60e51b815260206004820152600c60248201527f7a65726f20726577617264730000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b0384166000908152606f60209081526040808320868452909152812081815560018101829055600201556133d981613734565b5092915050565b6000828201838110156112bb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b61344382614754565b613494576040805162461bcd60e51b815260206004820152601760248201527f76616c696461746f7220646f65736e2774206578697374000000000000000000604482015290519081900360640190fd5b600082815260686020526040902054156134f5576040805162461bcd60e51b815260206004820152601660248201527f76616c696461746f722069736e27742061637469766500000000000000000000604482015290519081900360640190fd5b613502838383600161359c565b61350b82614824565b61172a5760405162461bcd60e51b81526004018080602001828103825260298152602001806151976029913960400191505060405180910390fd5b60006112bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506148ec565b6066546001600160a01b0390811691161490565b600082116135f1576040805162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015290519081900360640190fd5b6135fb848461388d565b506001600160a01b0384166000908152607260209081526040808320868452909152902054613630908363ffffffff6133e016565b6001600160a01b0385166000908152607260209081526040808320878452825280832093909355606890522060030154613670818463ffffffff6133e016565b600085815260686020526040902060030155606c54613695908463ffffffff6133e016565b606c556000848152606860205260409020546136c257606d546136be908463ffffffff6133e016565b606d555b6136cd848215612e0f565b60408051848152905185916001600160a01b038816917f9a8f44850296624dadfd9c246d17e47171d35727a181bd090aa14bbbe00238bb9181900360200190a36000848152606860205260409020600601546118f79086906001600160a01b031684613f23565b606654604080517f66e7ea0f0000000000000000000000000000000000000000000000000000000081523060048201526024810184905290516001600160a01b03909216916366e7ea0f9160448082019260009290919082900301818387803b1580156137a057600080fd5b505af11580156137b4573d6000803e3d6000fd5b50506076546137cc925090508263ffffffff6133e016565b60765550565b607b546000906001600160a01b03166137ed575060016112be565b607b54604080517f21d585c30000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015260248201869052915191909216916321d585c3916044808301926020929190829003018186803b15801561385a57600080fd5b505afa15801561386e573d6000803e3d6000fd5b505050506040513d602081101561388457600080fd5b50519392505050565b6000613897615024565b6138a18484614983565b90506138ac83614abb565b6001600160a01b0385166000818152607060209081526040808320888452825280832094909455918152606f8252828120868252825282902082516060810184528154815260018201549281019290925260020154918101919091526139129082614b16565b6001600160a01b0385166000818152606f602090815260408083208884528252808320855181558583015160018083019190915595820151600291820155938352607482528083208884528252918290208251606081018452815481529481015491850191909152909101549082015261398c9082614b16565b6001600160a01b0385166000908152607460209081526040808320878452825291829020835181559083015160018201559101516002909101556139d08484613064565b613a33576001600160a01b0384166000818152607360209081526040808320878452825280832083815560018082018590556002808301869055600390920185905594845260748352818420888552909252822082815592830182905591909101555b6020810151151580613a455750805115155b806127ae57506040015115159392505050565b6001600160a01b03841660009081526074602090815260408083208684529091528120548190613aa0908490613a94908763ffffffff614b8816565b9063ffffffff614be116565b6001600160a01b038716600090815260746020908152604080832089845290915281206001015491925090613ae1908590613a94908863ffffffff614b8816565b6001600160a01b03881660009081526074602090815260408083208a845290915290205490915060028204830190613b199084613546565b6001600160a01b03891660009081526074602090815260408083208b8452909152902090815560010154613b4d9083613546565b6001600160a01b03891660009081526074602090815260408083208b8452909152902060010155858110613b7e5750845b979650505050505050565b6001600160a01b03841660009081526072602090815260408083208684528252808320805486900390556068909152902060030154613bce908363ffffffff61354616565b600084815260686020526040902060030155606c54613bf3908363ffffffff61354616565b606c55600083815260686020526040902054613c2057606d54613c1c908363ffffffff61354616565b606d555b6000613c2b8461271f565b90508015613d5d57600084815260686020526040902054613d5857608160009054906101000a90046001600160a01b03166001600160a01b031663c5f530af6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c9457600080fd5b505afa158015613ca8573d6000803e3d6000fd5b505050506040513d6020811015613cbe57600080fd5b5051811015613d14576040805162461bcd60e51b815260206004820152601760248201527f696e73756666696369656e742073656c662d7374616b65000000000000000000604482015290519081900360640190fd5b613d1d84614824565b613d585760405162461bcd60e51b81526004018080602001828103825260298152602001806151976029913960400191505060405180910390fd5b613d68565b613d68846001613df9565b6000848152606860205260409020600601546118f79086906001600160a01b031684613f23565b8015612afc5760405160009082156108fc0290839083818181858288f19350505050158015613dc2573d6000803e3d6000fd5b506040805182815290517f8918bd6046d08b314e457977f29562c5d76a7030d79b1edba66e8a5da0b77ae89181900360200190a150565b600082815260686020526040902054158015613e1457508015155b15613e4157600082815260686020526040902060030154606d54613e3d9163ffffffff61354616565b606d555b600082815260686020526040902054811115612a7657600082815260686020526040902081815560020154613ee957613e7861293d565b600083815260686020526040902060020155613e926140cd565b6000838152606860209081526040918290206001810184905560020154825190815290810192909252805184927fac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e4792908290030190a25b60408051828152905183917fcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e919081900360200190a25050565b6082546001600160a01b03161561172a57608254604080516001600160a01b03868116602483015285811660448084019190915283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f4a7702bb00000000000000000000000000000000000000000000000000000000178152925182516000959290921693627a120093928291908083835b6020831061400657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613fc9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d8060008114614069576040519150601f19603f3d011682016040523d82523d6000602084013e61406e565b606091505b50509050808061407c575081155b612dcb576040805162461bcd60e51b815260206004820152601b60248201527f676f7620766f746573207265636f756e74696e67206661696c65640000000000604482015290519081900360640190fd5b4290565b60008215806140e757506140e3614133565b8210155b156140f45750600061412c565b61411f6001611125614104614133565b613a9486614110614133565b8a91900363ffffffff614b8816565b90508381111561412c5750825b9392505050565b670de0b6b3a764000090565b6001600160a01b038816600090815260696020526040902054156141aa576040805162461bcd60e51b815260206004820152601860248201527f76616c696461746f7220616c7265616479206578697374730000000000000000604482015290519081900360640190fd5b6001600160a01b03881660008181526069602090815260408083208b90558a8352606882528083208981556004810189905560058101889055600181018690556002810187905560060180547fffffffffffffffffffffffff000000000000000000000000000000000000000016909417909355606a8152919020875161423392890190615045565b50876001600160a01b0316877f49bca1ed2666922f9f1690c26a569e1299c2a715fe57647d77e81adfabbf25bf8686604051808381526020018281526020019250505060405180910390a381156142bf576040805183815260208101839052815189927fac4801c32a6067ff757446524ee4e7a373797278ac3c883eac5c693b4ad72e47928290030190a25b84156142fc5760408051868152905188917fcd35267e7654194727477d6c78b541a553483cff7f92a055d17868d3da6e953e919081900360200190a25b5050505050505050565b61430e615024565b614316615024565b6143208484614983565b6001600160a01b0385166000908152606f6020908152604080832087845282529182902082516060810184528154815260018201549281019290925260020154918101919091529091506127ae9082614b16565b606b80546001019081905561172a838284600061438f61293d565b6143976140cd565b60008061413f565b6143a9848461123b565b8111156143fd576040805162461bcd60e51b815260206004820152601060248201527f6e6f7420656e6f756768207374616b6500000000000000000000000000000000604482015290519081900360640190fd5b6000838152606860205260409020541561445e576040805162461bcd60e51b815260206004820152601660248201527f76616c696461746f722069736e27742061637469766500000000000000000000604482015290519081900360640190fd5b608160009054906101000a90046001600160a01b03166001600160a01b0316630d7b26096040518163ffffffff1660e01b815260040160206040518083038186803b1580156144ac57600080fd5b505afa1580156144c0573d6000803e3d6000fd5b505050506040513d60208110156144d657600080fd5b505182108015906145605750608160009054906101000a90046001600160a01b03166001600160a01b0316630d4955e36040518163ffffffff1660e01b815260040160206040518083038186803b15801561453057600080fd5b505afa158015614544573d6000803e3d6000fd5b505050506040513d602081101561455a57600080fd5b50518211155b6145b1576040805162461bcd60e51b815260206004820152601260248201527f696e636f7272656374206475726174696f6e0000000000000000000000000000604482015290519081900360640190fd5b60006145bf836111256140cd565b6000858152606860205260409020600601549091506001600160a01b03908116908616811461464d576001600160a01b038116600090815260736020908152604080832088845290915290206002015482111561464d5760405162461bcd60e51b815260040180806020018281038252602881526020018061516f6028913960400191505060405180910390fd5b614657868661388d565b506001600160a01b0386166000908152607360209081526040808320888452909152902060038101548510156146d4576040805162461bcd60e51b815260206004820152601f60248201527f6c6f636b7570206475726174696f6e2063616e6e6f7420646563726561736500604482015290519081900360640190fd5b80546146e6908563ffffffff6133e016565b81556146f061293d565b600182015560028101839055600381018590556040805186815260208101869052815188926001600160a01b038b16927f138940e95abffcd789b497bf6188bba3afa5fbd22fb5c42c2f6018d1bf0f4e78929081900390910190a350505050505050565b600090815260686020526040902060050154151590565b6001600160a01b0381166147b05760405162461bcd60e51b81526004018080602001828103825260268152602001806150de6026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60006148d1614831614133565b608154604080517f2265f2840000000000000000000000000000000000000000000000000000000081529051613a94926001600160a01b031691632265f284916004808301926020929190829003018186803b15801561489057600080fd5b505afa1580156148a4573d6000803e3d6000fd5b505050506040513d60208110156148ba57600080fd5b50516148c58661271f565b9063ffffffff614b8816565b60008381526068602052604090206003015411159050919050565b6000818484111561497b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614940578181015183820152602001614928565b50505050905090810190601f16801561496d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b61498b615024565b6001600160a01b0383166000908152607060209081526040808320858452909152812054906149b984614abb565b905060006149c78686614c23565b9050818111156149d45750805b828110156149df5750815b6001600160a01b03861660008181526073602090815260408083208984528252808320938352607282528083208984529091528120548254909190614a2b90839063ffffffff61354616565b90506000614a3f84600001548a8988614d00565b9050614a49615024565b614a57828660030154614d63565b9050614a65838b8a89614d00565b9150614a6f615024565b614a7a836000614d63565b9050614a88858c898b614d00565b9250614a92615024565b614a9d846000614d63565b9050614aaa838383614f24565b9d9c50505050505050505050505050565b60008181526068602052604081206002015415614b0e576000828152606860205260409020600201546067541015614af65750606754612750565b50600081815260686020526040902060020154612750565b505060675490565b614b1e615024565b6040805160608101909152825184518291614b3f919063ffffffff6133e016565b8152602001614b5f846020015186602001516133e090919063ffffffff16565b8152602001614b7f846040015186604001516133e090919063ffffffff16565b90529392505050565b600082614b97575060006112be565b82820282848281614ba457fe5b04146112bb5760405162461bcd60e51b815260040180806020018281038252602181526020018061512d6021913960400191505060405180910390fd5b60006112bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614f3f565b6001600160a01b0382166000908152607360209081526040808320848452909152812060010154606754614c58858583614fa4565b15614c665791506112be9050565b614c71858584614fa4565b614c80576000925050506112be565b80821115614c93576000925050506112be565b80821015614cc657600281830104614cac868683614fa4565b15614cbc57806001019250614cc0565b8091505b50614c93565b80614cd6576000925050506112be565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01949350505050565b6000818310614d11575060006127ae565b600083815260776020818152604080842088855260019081018352818520548786529383528185208986520190915290912054613b7e614d4f614133565b613a94896148c5858763ffffffff61354616565b614d6b615024565b60405180606001604052806000815260200160008152602001600081525090506000608160009054906101000a90046001600160a01b03166001600160a01b0316635e2308d26040518163ffffffff1660e01b815260040160206040518083038186803b158015614ddb57600080fd5b505afa158015614def573d6000803e3d6000fd5b505050506040513d6020811015614e0557600080fd5b505190508215614efd57600081614e1a614133565b0390506000614eac608160009054906101000a90046001600160a01b03166001600160a01b0316630d4955e36040518163ffffffff1660e01b815260040160206040518083038186803b158015614e7057600080fd5b505afa158015614e84573d6000803e3d6000fd5b505050506040513d6020811015614e9a57600080fd5b5051613a94848863ffffffff614b8816565b90506000614ecd614ebb614133565b613a948987860163ffffffff614b8816565b9050614eea614eda614133565b613a94898763ffffffff614b8816565b6020860181905290038452506133d99050565b614f18614f08614133565b613a94868463ffffffff614b8816565b60408301525092915050565b614f2c615024565b6127ae614f398585614b16565b83614b16565b60008183614f8e5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614940578181015183820152602001614928565b506000838581614f9a57fe5b0495945050505050565b6001600160a01b038316600090815260736020908152604080832085845290915281206001015482108015906127ae57506001600160a01b03841660009081526073602090815260408083208684529091529020600201546150058361500f565b1115949350505050565b60009081526077602052604090206007015490565b60405180606001604052806000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061508657805160ff19168380011785556150b3565b828001600101855582156150b3579182015b828111156150b3578251825591602001919060010190615098565b506150bf9291506150c3565b5090565b61294491905b808211156150bf57600081556001016150c956fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737363616c6c6572206973206e6f7420746865204e6f64654472697665724175746820636f6e7472616374536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f776d757374206265206c657373207468616e206f7220657175616c20746f20312e3076616c696461746f72206c6f636b757020706572696f642077696c6c20656e64206561726c69657276616c696461746f7227732064656c65676174696f6e73206c696d69742069732065786365656465646c6f636b6564207374616b652069732067726561746572207468616e207468652077686f6c65207374616b65a265627a7a72315820b767b9bd00adb5f0467097fa60a9e2cfcb624e12e00375239584e1338e314fe964736f6c63430005110032" diff --git a/evm/go-x1/gossip/contract/solc/.gitignore b/evm/go-x1/gossip/contract/solc/.gitignore deleted file mode 100644 index 1044a10..0000000 --- a/evm/go-x1/gossip/contract/solc/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.json -*.abi -*.bin -*.bin-runtime diff --git a/evm/go-x1/gossip/discover.go b/evm/go-x1/gossip/discover.go deleted file mode 100644 index a9a2773..0000000 --- a/evm/go-x1/gossip/discover.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package gossip - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/forkid" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/evmcore" -) - -// enrEntry is the ENR entry which advertises `eth` protocol on the discovery. -type enrEntry struct { - ForkID forkid.ID // Fork identifier per EIP-2124 - - // Ignore additional fields (for forward compatibility). - Rest []rlp.RawValue `rlp:"tail"` -} - -// ENRKey implements enr.Entry. -func (e enrEntry) ENRKey() string { - return "opera" -} - -// StartENRUpdater starts the `opera` ENR updater loop, which listens for chain -// head events and updates the requested node record whenever a fork is passed. -func StartENRUpdater(svc *Service, ln *enode.LocalNode) { - var newHead = make(chan evmcore.ChainHeadNotify, 10) - sub := svc.feed.SubscribeNewBlock(newHead) - - go func() { - defer sub.Unsubscribe() - for { - select { - case <-newHead: - ln.Set(currentENREntry(svc)) - case <-sub.Err(): - // Would be nice to sync with Stop, but there is no - // good way to do that. - return - } - } - }() -} - -// currentENREntry constructs an `eth` ENR entry based on the current state of the chain. -func currentENREntry(svc *Service) *enrEntry { - genesisHash := *svc.store.GetGenesisID() - return &enrEntry{ - ForkID: forkid.NewID(svc.store.GetEvmChainConfig(), common.Hash(genesisHash), uint64(svc.store.GetLatestBlockIndex())), - } -} diff --git a/evm/go-x1/gossip/dummy_tx_pool.go b/evm/go-x1/gossip/dummy_tx_pool.go deleted file mode 100644 index b9397ce..0000000 --- a/evm/go-x1/gossip/dummy_tx_pool.go +++ /dev/null @@ -1,169 +0,0 @@ -package gossip - -import ( - "math/rand" - "sort" - "sync" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - notify "github.com/ethereum/go-ethereum/event" - - "github.com/Fantom-foundation/go-opera/evmcore" -) - -// dummyTxPool is a fake, helper transaction pool for testing purposes -type dummyTxPool struct { - txFeed notify.Feed - pool []*types.Transaction // Collection of all transactions - added chan<- []*types.Transaction // Notification channel for new transactions - - signer types.Signer - - lock sync.RWMutex // Protects the transaction pool -} - -// AddRemotes appends a batch of transactions to the pool, and notifies any -// listeners if the addition channel is non nil -func (p *dummyTxPool) AddRemotes(txs []*types.Transaction) []error { - p.lock.Lock() - defer p.lock.Unlock() - - p.pool = append(p.pool, txs...) - if p.added != nil { - p.added <- txs - } - return make([]error, len(txs)) -} - -func (p *dummyTxPool) AddLocals(txs []*types.Transaction) []error { - return p.AddRemotes(txs) -} - -func (p *dummyTxPool) AddLocal(tx *types.Transaction) error { - return p.AddLocals([]*types.Transaction{tx})[0] -} - -func (p *dummyTxPool) Nonce(addr common.Address) uint64 { - return 0 -} - -func (p *dummyTxPool) Stats() (int, int) { - return p.Count(), 0 -} - -func (p *dummyTxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { - return nil, nil -} - -func (p *dummyTxPool) ContentFrom(addr common.Address) (types.Transactions, types.Transactions) { - return nil, nil -} - -// Pending returns all the transactions known to the pool -func (p *dummyTxPool) Pending(enforceTips bool) (map[common.Address]types.Transactions, error) { - p.lock.RLock() - defer p.lock.RUnlock() - - batches := make(map[common.Address]types.Transactions) - for _, tx := range p.pool { - from, _ := types.Sender(p.signer, tx) - batches[from] = append(batches[from], tx) - } - for _, batch := range batches { - sort.Sort(types.TxByNonce(batch)) - } - return batches, nil -} - -func (p *dummyTxPool) SubscribeNewTxsNotify(ch chan<- evmcore.NewTxsNotify) notify.Subscription { - return p.txFeed.Subscribe(ch) -} - -func (p *dummyTxPool) Map() map[common.Hash]*types.Transaction { - p.lock.RLock() - defer p.lock.RUnlock() - res := make(map[common.Hash]*types.Transaction, len(p.pool)) - for _, tx := range p.pool { - res[tx.Hash()] = tx - } - return nil -} - -func (p *dummyTxPool) Get(txid common.Hash) *types.Transaction { - p.lock.RLock() - defer p.lock.RUnlock() - for _, tx := range p.pool { - if tx.Hash() == txid { - return tx - } - } - return nil -} - -func (p *dummyTxPool) Has(txid common.Hash) bool { - p.lock.RLock() - defer p.lock.RUnlock() - for _, tx := range p.pool { - if tx.Hash() == txid { - return true - } - } - return false -} - -func (p *dummyTxPool) OnlyNotExisting(txids []common.Hash) []common.Hash { - m := p.Map() - notExisting := make([]common.Hash, 0, len(txids)) - for _, txid := range txids { - if m[txid] == nil { - notExisting = append(notExisting, txid) - } - } - return notExisting -} - -func (p *dummyTxPool) SampleHashes(max int) []common.Hash { - p.lock.RLock() - defer p.lock.RUnlock() - res := make([]common.Hash, 0, max) - skip := 0 - if len(p.pool) > max { - skip = rand.Intn(len(p.pool) - max) - } - for _, tx := range p.pool { - if len(res) >= max { - break - } - if skip > 0 { - skip-- - continue - } - res = append(res, tx.Hash()) - } - return res -} - -func (p *dummyTxPool) Count() int { - return len(p.pool) -} - -func (p *dummyTxPool) Clear() { - p.lock.Lock() - defer p.lock.Unlock() - if len(p.pool) != 0 { - p.pool = p.pool[:0] - } -} - -func (p *dummyTxPool) Delete(needle common.Hash) { - p.lock.Lock() - defer p.lock.Unlock() - notErased := make([]*types.Transaction, 0, len(p.pool)-1) - for _, tx := range p.pool { - if tx.Hash() != needle { - notErased = append(notErased, tx) - } - } - p.pool = notErased -} diff --git a/evm/go-x1/gossip/emitter/config.go b/evm/go-x1/gossip/emitter/config.go deleted file mode 100644 index a56c072..0000000 --- a/evm/go-x1/gossip/emitter/config.go +++ /dev/null @@ -1,106 +0,0 @@ -package emitter - -import ( - "math/rand" - "time" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/opera" -) - -// EmitIntervals is the configuration of emit intervals. -type EmitIntervals struct { - Min time.Duration - Max time.Duration - Confirming time.Duration // emit time when there's no txs to originate, but at least 1 tx to confirm - ParallelInstanceProtection time.Duration - DoublesignProtection time.Duration -} - -type ValidatorConfig struct { - ID idx.ValidatorID - PubKey validatorpk.PubKey -} - -type FileConfig struct { - Path string - SyncMode bool -} - -// Config is the configuration of events emitter. -type Config struct { - VersionToPublish string - - Validator ValidatorConfig - - EmitIntervals EmitIntervals // event emission intervals - - MaxTxsPerAddress int - - MaxParents idx.Event - - // thresholds on GasLeft - LimitedTpsThreshold uint64 - NoTxsThreshold uint64 - EmergencyThreshold uint64 - - TxsCacheInvalidation time.Duration - - PrevEmittedEventFile FileConfig - PrevBlockVotesFile FileConfig - PrevEpochVoteFile FileConfig -} - -// DefaultConfig returns the default configurations for the events emitter. -func DefaultConfig() Config { - return Config{ - VersionToPublish: params.VersionWithMeta(), - - EmitIntervals: EmitIntervals{ - Min: 150 * time.Millisecond, - Max: 10 * time.Minute, - Confirming: 170 * time.Millisecond, - DoublesignProtection: 27 * time.Minute, // should be greater than MaxEmitInterval - ParallelInstanceProtection: 1 * time.Minute, - }, - - MaxTxsPerAddress: TxTurnNonces, - - MaxParents: 0, - - LimitedTpsThreshold: opera.DefaultEventGas * 120, - NoTxsThreshold: opera.DefaultEventGas * 30, - EmergencyThreshold: opera.DefaultEventGas * 5, - - TxsCacheInvalidation: 200 * time.Millisecond, - } -} - -// RandomizeEmitTime and return new config -func (cfg EmitIntervals) RandomizeEmitTime(r *rand.Rand) EmitIntervals { - config := cfg - // value = value - 0.1 * value + 0.1 * random value - if config.Max > 10 { - config.Max = config.Max - config.Max/10 + time.Duration(r.Int63n(int64(config.Max/10))) - } - // value = value + 0.33 * random value - if config.DoublesignProtection > 3 { - config.DoublesignProtection = config.DoublesignProtection + time.Duration(r.Int63n(int64(config.DoublesignProtection/3))) - } - return config -} - -// FakeConfig returns the testing configurations for the events emitter. -func FakeConfig(num idx.Validator) Config { - cfg := DefaultConfig() - cfg.EmitIntervals.Max = 10 * time.Second // don't wait long in fakenet - cfg.EmitIntervals.DoublesignProtection = cfg.EmitIntervals.Max / 2 - if num <= 1 { - // disable self-fork protection if fakenet 1/1 - cfg.EmitIntervals.DoublesignProtection = 0 - } - return cfg -} diff --git a/evm/go-x1/gossip/emitter/control.go b/evm/go-x1/gossip/emitter/control.go deleted file mode 100644 index 5feebea..0000000 --- a/evm/go-x1/gossip/emitter/control.go +++ /dev/null @@ -1,140 +0,0 @@ -package emitter - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/emitter/ancestor" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/utils/piecefunc" - - "github.com/Fantom-foundation/go-opera/inter" -) - -func scalarUpdMetric(diff idx.Event, weight pos.Weight, totalWeight pos.Weight) ancestor.Metric { - return ancestor.Metric(scalarUpdMetricF(uint64(diff)*piecefunc.DecimalUnit)) * ancestor.Metric(weight) / ancestor.Metric(totalWeight) -} - -func updMetric(median, cur, upd idx.Event, validatorIdx idx.Validator, validators *pos.Validators) ancestor.Metric { - if upd <= median || upd <= cur { - return 0 - } - weight := validators.GetWeightByIdx(validatorIdx) - if median < cur { - return scalarUpdMetric(upd-median, weight, validators.TotalWeight()) - scalarUpdMetric(cur-median, weight, validators.TotalWeight()) - } - return scalarUpdMetric(upd-median, weight, validators.TotalWeight()) -} - -func kickStartMetric(metric ancestor.Metric, seq idx.Event) ancestor.Metric { - // kickstart metric in a beginning of epoch, when there's nothing to observe yet - if seq <= 2 && metric < 0.9*piecefunc.DecimalUnit { - metric += 0.1 * piecefunc.DecimalUnit - } - if seq <= 1 && metric <= 0.8*piecefunc.DecimalUnit { - metric += 0.2 * piecefunc.DecimalUnit - } - return metric -} - -func eventMetric(orig ancestor.Metric, seq idx.Event) ancestor.Metric { - return kickStartMetric(ancestor.Metric(eventMetricF(uint64(orig))), seq) -} - -func (em *Emitter) isAllowedToEmit(e inter.EventI, eTxs bool, metric ancestor.Metric, selfParent *inter.Event) bool { - passedTime := e.CreationTime().Time().Sub(em.prevEmittedAtTime) - if passedTime < 0 { - passedTime = 0 - } - passedTimeIdle := e.CreationTime().Time().Sub(em.prevIdleTime) - if passedTimeIdle < 0 { - passedTimeIdle = 0 - } - if em.stakeRatio[e.Creator()] < 0.35*piecefunc.DecimalUnit { - // top validators emit event right after transaction is originated - passedTimeIdle = passedTime - } else if em.stakeRatio[e.Creator()] < 0.7*piecefunc.DecimalUnit { - // top validators emit event right after transaction is originated - passedTimeIdle = (passedTimeIdle + passedTime) / 2 - } - if passedTimeIdle > passedTime { - passedTimeIdle = passedTime - } - // metric is a decimal (0.0, 1.0], being an estimation of how much the event will advance the consensus - adjustedPassedTime := time.Duration(ancestor.Metric(passedTime/piecefunc.DecimalUnit) * metric) - adjustedPassedIdleTime := time.Duration(ancestor.Metric(passedTimeIdle/piecefunc.DecimalUnit) * metric) - passedBlocks := em.world.GetLatestBlockIndex() - em.prevEmittedAtBlock - // Forbid emitting if not enough power and power is decreasing - { - threshold := em.config.EmergencyThreshold - if e.GasPowerLeft().Min() <= threshold { - if selfParent != nil && e.GasPowerLeft().Min() < selfParent.GasPowerLeft().Min() { - em.Periodic.Warn(10*time.Second, "Not enough power to emit event, waiting", - "power", e.GasPowerLeft().String(), - "selfParentPower", selfParent.GasPowerLeft().String(), - "stake%", 100*float64(em.validators.Get(e.Creator()))/float64(em.validators.TotalWeight())) - return false - } - } - } - // Enforce emitting if passed too many time/blocks since previous event - { - rules := em.world.GetRules() - maxBlocks := rules.Economy.BlockMissedSlack/2 + 1 - if rules.Economy.BlockMissedSlack > maxBlocks && maxBlocks < rules.Economy.BlockMissedSlack-5 { - maxBlocks = rules.Economy.BlockMissedSlack - 5 - } - if passedTime >= em.intervals.Max || - passedBlocks >= maxBlocks*4/5 && metric >= piecefunc.DecimalUnit/2 || - passedBlocks >= maxBlocks { - return true - } - } - // Slow down emitting if power is low - { - threshold := (em.config.NoTxsThreshold + em.config.EmergencyThreshold) / 2 - if e.GasPowerLeft().Min() <= threshold { - // it's emitter, so no need in determinism => fine to use float - minT := float64(em.intervals.Min) - maxT := float64(em.intervals.Max) - factor := float64(e.GasPowerLeft().Min()) / float64(threshold) - adjustedEmitInterval := time.Duration(maxT - (maxT-minT)*factor) - if passedTime < adjustedEmitInterval { - return false - } - } - } - // Slow down emitting if no txs to confirm/originate - { - if passedTime < em.intervals.Max && - em.idle() && - !eTxs { - return false - } - } - // Emitting is controlled by the efficiency metric - { - if passedTime < em.intervals.Min { - return false - } - if adjustedPassedTime < em.intervals.Min && - !em.idle() { - return false - } - if adjustedPassedIdleTime < em.intervals.Confirming && - !em.idle() && - !eTxs { - return false - } - } - - return true -} - -func (em *Emitter) recheckIdleTime() { - em.world.Lock() - defer em.world.Unlock() - if em.idle() { - em.prevIdleTime = time.Now() - } -} diff --git a/evm/go-x1/gossip/emitter/emitter.go b/evm/go-x1/gossip/emitter/emitter.go deleted file mode 100644 index 163127f..0000000 --- a/evm/go-x1/gossip/emitter/emitter.go +++ /dev/null @@ -1,464 +0,0 @@ -package emitter - -import ( - "errors" - "fmt" - "math/rand" - "os" - "strings" - "sync" - "time" - - "github.com/Fantom-foundation/lachesis-base/emitter/ancestor" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/utils/piecefunc" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/gossip/emitter/originatedtxs" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/tracing" - "github.com/Fantom-foundation/go-opera/utils/errlock" - "github.com/Fantom-foundation/go-opera/utils/rate" -) - -const ( - SenderCountBufferSize = 20000 - PayloadIndexerSize = 5000 -) - -type Emitter struct { - config Config - - world World - - syncStatus syncStatus - - prevIdleTime time.Time - prevEmittedAtTime time.Time - prevEmittedAtBlock idx.Block - originatedTxs *originatedtxs.Buffer - pendingGas uint64 - - // note: track validators and epoch internally to avoid referring to - // validators of a future epoch inside OnEventConnected of last epoch event - validators *pos.Validators - epoch idx.Epoch - - // challenges is deadlines when each validator should emit an event - challenges map[idx.ValidatorID]time.Time - // offlineValidators is a map of validators which are likely to be offline - // This map may be different on different instances - offlineValidators map[idx.ValidatorID]bool - expectedEmitIntervals map[idx.ValidatorID]time.Duration - stakeRatio map[idx.ValidatorID]uint64 - - prevRecheckedChallenges time.Time - - quorumIndexer *ancestor.QuorumIndexer - fcIndexer *ancestor.FCIndexer - payloadIndexer *ancestor.PayloadIndexer - - intervals EmitIntervals - globalConfirmingInterval time.Duration - - done chan struct{} - wg sync.WaitGroup - - maxParents idx.Event - - cache struct { - sortedTxs *types.TransactionsByPriceAndNonce - poolTime time.Time - poolBlock idx.Block - poolCount int - } - - emittedEventFile *os.File - emittedBvsFile *os.File - emittedEvFile *os.File - busyRate *rate.Gauge - - logger.Periodic -} - -// NewEmitter creation. -func NewEmitter( - config Config, - world World, -) *Emitter { - // Randomize event time to decrease chance of 2 parallel instances emitting event at the same time - // It increases the chance of detecting parallel instances - r := rand.New(rand.NewSource(time.Now().UnixNano())) - config.EmitIntervals = config.EmitIntervals.RandomizeEmitTime(r) - - return &Emitter{ - config: config, - world: world, - originatedTxs: originatedtxs.New(SenderCountBufferSize), - intervals: config.EmitIntervals, - globalConfirmingInterval: config.EmitIntervals.Confirming, - Periodic: logger.Periodic{Instance: logger.New()}, - } -} - -// init emitter without starting events emission -func (em *Emitter) init() { - em.syncStatus.startup = time.Now() - em.syncStatus.lastConnected = time.Now() - em.syncStatus.p2pSynced = time.Now() - validators, epoch := em.world.GetEpochValidators() - em.OnNewEpoch(validators, epoch) - - if len(em.config.PrevEmittedEventFile.Path) != 0 { - em.emittedEventFile = openPrevActionFile(em.config.PrevEmittedEventFile.Path, em.config.PrevEmittedEventFile.SyncMode) - } - if len(em.config.PrevBlockVotesFile.Path) != 0 { - em.emittedBvsFile = openPrevActionFile(em.config.PrevBlockVotesFile.Path, em.config.PrevBlockVotesFile.SyncMode) - } - if len(em.config.PrevEpochVoteFile.Path) != 0 { - em.emittedEvFile = openPrevActionFile(em.config.PrevEpochVoteFile.Path, em.config.PrevEpochVoteFile.SyncMode) - } - em.busyRate = rate.NewGauge() -} - -// Start starts event emission. -func (em *Emitter) Start() { - if em.config.Validator.ID == 0 { - // short circuit if not a validator - return - } - if em.done != nil { - return - } - em.init() - em.done = make(chan struct{}) - - done := em.done - if em.config.EmitIntervals.Min == 0 { - return - } - em.wg.Add(1) - go func() { - defer em.wg.Done() - tick := 11 * time.Millisecond - timer := time.NewTimer(tick) - defer timer.Stop() - for { - select { - case <-timer.C: - em.tick() - timer.Reset(tick) - case <-done: - return - } - } - }() -} - -// Stop stops event emission. -func (em *Emitter) Stop() { - if em.done == nil { - return - } - - close(em.done) - em.done = nil - em.wg.Wait() - em.busyRate.Stop() -} - -func (em *Emitter) tick() { - // track synced time - if em.world.PeersNum() == 0 { - // connected time ~= last time when it's true that "not connected yet" - em.syncStatus.lastConnected = time.Now() - } - if !em.world.IsSynced() { - // synced time ~= last time when it's true that "not synced yet" - em.syncStatus.p2pSynced = time.Now() - } - if em.idle() { - em.busyRate.Mark(0) - } else { - em.busyRate.Mark(1) - } - if em.world.IsBusy() { - return - } - - em.recheckChallenges() - em.recheckIdleTime() - if time.Since(em.prevEmittedAtTime) >= em.intervals.Min { - _, _ = em.EmitEvent() - } -} - -func (em *Emitter) getSortedTxs() *types.TransactionsByPriceAndNonce { - // Short circuit if pool wasn't updated since the cache was built - poolCount := em.world.TxPool.Count() - if em.cache.sortedTxs != nil && - em.cache.poolBlock == em.world.GetLatestBlockIndex() && - em.cache.poolCount == poolCount && - time.Since(em.cache.poolTime) < em.config.TxsCacheInvalidation { - return em.cache.sortedTxs.Copy() - } - // Build the cache - pendingTxs, err := em.world.TxPool.Pending(true) - if err != nil { - em.Log.Error("Tx pool transactions fetching error", "err", err) - return nil - } - for from, txs := range pendingTxs { - // Filter the excessive transactions from each sender - if len(txs) > em.config.MaxTxsPerAddress { - pendingTxs[from] = txs[:em.config.MaxTxsPerAddress] - } - } - sortedTxs := types.NewTransactionsByPriceAndNonce(em.world.TxSigner, pendingTxs, em.world.GetRules().Economy.MinGasPrice) - em.cache.sortedTxs = sortedTxs - em.cache.poolCount = poolCount - em.cache.poolBlock = em.world.GetLatestBlockIndex() - em.cache.poolTime = time.Now() - return sortedTxs.Copy() -} - -func (em *Emitter) EmitEvent() (*inter.EventPayload, error) { - if em.config.Validator.ID == 0 { - // short circuit if not a validator - return nil, nil - } - sortedTxs := em.getSortedTxs() - - if em.world.IsBusy() { - return nil, nil - } - em.world.Lock() - defer em.world.Unlock() - - e, err := em.createEvent(sortedTxs) - if e == nil || err != nil { - return nil, err - } - em.syncStatus.prevLocalEmittedID = e.ID() - - err = em.world.Process(e) - if err != nil { - em.Log.Error("Self-event connection failed", "err", err.Error()) - return nil, err - } - // write event ID to avoid doublesigning in future after a crash - em.writeLastEmittedEventID(e.ID()) - if e.EpochVote().Epoch != 0 { - em.writeLastEmittedEpochVote(e.EpochVote().Epoch) - } - if len(e.BlockVotes().Votes) != 0 { - em.writeLastEmittedBlockVotes(e.BlockVotes().LastBlock()) - } - // broadcast the event - em.world.Broadcast(e) - - em.prevEmittedAtTime = time.Now() // record time after connecting, to add the event processing time" - em.prevEmittedAtBlock = em.world.GetLatestBlockIndex() - - // metrics - if tracing.Enabled() { - for _, t := range e.Txs() { - span := tracing.CheckTx(t.Hash(), "Emitter.EmitEvent()") - defer span.Finish() - } - } - - return e, nil -} - -func (em *Emitter) loadPrevEmitTime() time.Time { - prevEventID := em.world.GetLastEvent(em.epoch, em.config.Validator.ID) - if prevEventID == nil { - return em.prevEmittedAtTime - } - prevEvent := em.world.GetEvent(*prevEventID) - if prevEvent == nil { - return em.prevEmittedAtTime - } - return prevEvent.CreationTime().Time() -} - -// createEvent is not safe for concurrent use. -func (em *Emitter) createEvent(sortedTxs *types.TransactionsByPriceAndNonce) (*inter.EventPayload, error) { - if !em.isValidator() { - return nil, nil - } - - if synced := em.logSyncStatus(em.isSyncedToEmit()); !synced { - // I'm reindexing my old events, so don't create events until connect all the existing self-events - return nil, nil - } - - var ( - selfParentSeq idx.Event - selfParentTime inter.Timestamp - parents hash.Events - maxLamport idx.Lamport - ) - - // Find parents - selfParent, parents, ok := em.chooseParents(em.epoch, em.config.Validator.ID) - if !ok { - return nil, nil - } - prevEmitted := em.readLastEmittedEventID() - if prevEmitted != nil && prevEmitted.Epoch() >= em.epoch { - if selfParent == nil || *selfParent != *prevEmitted { - errlock.Permanent(errors.New("Local database is corrupted, which may lead to a doublesign")) - } - } - - // Set parent-dependent fields - parentHeaders := make(inter.Events, len(parents)) - for i, p := range parents { - parent := em.world.GetEvent(p) - if parent == nil { - em.Log.Crit("Emitter: head not found", "mutEvent", p.String()) - } - parentHeaders[i] = parent - if parentHeaders[i].Creator() == em.config.Validator.ID && i != 0 { - // there are 2 heads from me, i.e. due to a fork, chooseParents could have found multiple self-parents - em.Periodic.Error(5*time.Second, "I've created a fork, events emitting isn't allowed", "creator", em.config.Validator.ID) - return nil, nil - } - maxLamport = idx.MaxLamport(maxLamport, parent.Lamport()) - } - - selfParentSeq = 0 - selfParentTime = 0 - var selfParentHeader *inter.Event - if selfParent != nil { - selfParentHeader = parentHeaders[0] - selfParentSeq = selfParentHeader.Seq() - selfParentTime = selfParentHeader.CreationTime() - } - - version := uint8(0) - if em.world.GetRules().Upgrades.Llr { - version = 1 - } - - mutEvent := &inter.MutableEventPayload{} - mutEvent.SetVersion(version) - mutEvent.SetEpoch(em.epoch) - mutEvent.SetSeq(selfParentSeq + 1) - mutEvent.SetCreator(em.config.Validator.ID) - - mutEvent.SetParents(parents) - mutEvent.SetLamport(maxLamport + 1) - mutEvent.SetCreationTime(inter.MaxTimestamp(inter.Timestamp(time.Now().UnixNano()), selfParentTime+1)) - - // add LLR votes - em.addLlrEpochVote(mutEvent) - em.addLlrBlockVotes(mutEvent) - - // node version - if mutEvent.Seq() <= 1 && len(em.config.VersionToPublish) > 0 { - version := []byte("v-" + em.config.VersionToPublish) - if uint32(len(version)) <= em.world.GetRules().Dag.MaxExtraData { - mutEvent.SetExtra(version) - } - } - - // set consensus fields - var metric ancestor.Metric - err := em.world.Build(mutEvent, func() { - // calculate event metric when it is indexed by the vector clock - if em.fcIndexer != nil { - pastMe := em.fcIndexer.ValidatorsPastMe() - metric = (ancestor.Metric(pastMe) * piecefunc.DecimalUnit) / ancestor.Metric(em.validators.TotalWeight()) - if pastMe < em.validators.Quorum() { - metric /= 15 - } - if metric < 0.03*piecefunc.DecimalUnit { - metric = 0.03 * piecefunc.DecimalUnit - } - metric = overheadAdjustedEventMetricF(em.validators.Len(), uint64(em.busyRate.Rate1()*piecefunc.DecimalUnit), metric) - metric = kickStartMetric(metric, mutEvent.Seq()) - } else if em.quorumIndexer != nil { - metric = eventMetric(em.quorumIndexer.GetMetricOf(hash.Events{mutEvent.ID()}), mutEvent.Seq()) - metric = overheadAdjustedEventMetricF(em.validators.Len(), uint64(em.busyRate.Rate1()*piecefunc.DecimalUnit), metric) - } - }) - if err != nil { - if err == ErrNotEnoughGasPower { - em.Periodic.Warn(time.Second, "Not enough gas power to emit event. Too small stake?", - "stake%", 100*float64(em.validators.Get(em.config.Validator.ID))/float64(em.validators.TotalWeight())) - } else { - em.Log.Warn("Dropped event while emitting", "err", err) - } - return nil, nil - } - - // Pre-check if event should be emitted - // It is checked in advance to avoid adding transactions just to immediately drop the event later - if !em.isAllowedToEmit(mutEvent, true, metric, selfParentHeader) { - return nil, nil - } - - // Add txs - em.addTxs(mutEvent, sortedTxs) - - // Check if event should be emitted - // Check only if no txs were added, since check in a case with added txs was performed above - if mutEvent.Txs().Len() == 0 { - if !em.isAllowedToEmit(mutEvent, mutEvent.Txs().Len() != 0, metric, selfParentHeader) { - return nil, nil - } - } - - // calc Payload hash - mutEvent.SetPayloadHash(inter.CalcPayloadHash(mutEvent)) - - // sign - bSig, err := em.world.Signer.Sign(em.config.Validator.PubKey, mutEvent.HashToSign().Bytes()) - if err != nil { - em.Periodic.Error(time.Second, "Failed to sign event", "err", err) - return nil, err - } - var sig inter.Signature - copy(sig[:], bSig) - mutEvent.SetSig(sig) - - // build clean event - event := mutEvent.Build() - - // check - if err := em.world.Check(event, parentHeaders); err != nil { - em.Periodic.Error(time.Second, "Emitted incorrect event", "err", err) - return nil, err - } - - // set mutEvent name for debug - em.nameEventForDebug(event) - - return event, nil -} - -func (em *Emitter) idle() bool { - return em.originatedTxs.Empty() -} - -func (em *Emitter) isValidator() bool { - return em.config.Validator.ID != 0 && em.validators.Exists(em.config.Validator.ID) -} - -func (em *Emitter) nameEventForDebug(e *inter.EventPayload) { - name := []rune(hash.GetNodeName(e.Creator())) - if len(name) < 1 { - return - } - - name = name[len(name)-1:] - hash.SetEventName(e.ID(), fmt.Sprintf("%s%03d", - strings.ToLower(string(name)), - e.Seq())) -} diff --git a/evm/go-x1/gossip/emitter/emitter_llr.go b/evm/go-x1/gossip/emitter/emitter_llr.go deleted file mode 100644 index a65ce6e..0000000 --- a/evm/go-x1/gossip/emitter/emitter_llr.go +++ /dev/null @@ -1,125 +0,0 @@ -package emitter - -import ( - "math/rand" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/piecefunc" - - "github.com/Fantom-foundation/go-opera/eventcheck/basiccheck" - "github.com/Fantom-foundation/go-opera/inter" -) - -var emptyLlrBlockVotes = inter.LlrBlockVotes{ - Votes: []hash.Hash{}, -} - -func (em *Emitter) addLlrBlockVotes(e *inter.MutableEventPayload) { - if em.skipLlrBlockVote() || e.Version() == 0 { - e.SetBlockVotes(emptyLlrBlockVotes) - return - } - start := em.world.GetLowestBlockToDecide() - prevInDB := em.world.GetLastBV(e.Creator()) - if prevInDB != nil && start < *prevInDB+1 { - start = *prevInDB + 1 - } - prevInFile := em.readLastBlockVotes() - if prevInFile != nil && start < *prevInFile+1 { - start = *prevInFile + 1 - } - records := make([]hash.Hash, 0, basiccheck.MaxBlockVotesPerEvent) - epochEnd := false - var epoch idx.Epoch - for b := start; len(records) < basiccheck.MaxBlockVotesPerEvent; b++ { - blockEpoch := em.world.GetBlockEpoch(b) - if epoch == 0 { - if !em.isEpochValidator(blockEpoch) { - continue - } - epoch = blockEpoch - start = b - } - if epoch != blockEpoch || blockEpoch == 0 { - epochEnd = true - break - } - record := em.world.GetBlockRecordHash(b) - if record == nil { - break - } - records = append(records, *record) - } - - waitUntilLongerBatch := !epochEnd && len(records) < basiccheck.MaxBlockVotesPerEvent - if len(records) == 0 || waitUntilLongerBatch { - e.SetBlockVotes(emptyLlrBlockVotes) - return - } - e.SetBlockVotes(inter.LlrBlockVotes{ - Start: start, - Epoch: epoch, - Votes: records, - }) -} - -func (em *Emitter) addLlrEpochVote(e *inter.MutableEventPayload) { - if em.skipLlrEpochVote() || e.Version() == 0 { - return - } - target := em.world.GetLowestEpochToDecide() - prevInDB := em.world.GetLastEV(e.Creator()) - if prevInDB != nil && target < *prevInDB+1 { - target = *prevInDB + 1 - } - prevInFile := em.readLastEpochVote() - if prevInFile != nil && target < *prevInFile+1 { - target = *prevInFile + 1 - } - if !em.isEpochValidator(target) { - return - } - vote := em.world.GetEpochRecordHash(target) - if vote == nil { - return - } - e.SetEpochVote(inter.LlrEpochVote{ - Epoch: target, - Vote: *vote, - }) -} - -func (em *Emitter) neverSkipLlrVote() bool { - return em.stakeRatio[em.config.Validator.ID] <= uint64(piecefunc.DecimalUnit)/3+1 -} - -func (em *Emitter) skipLlrBlockVote() bool { - if em.neverSkipLlrVote() { - return false - } - // poor validators vote only if we have a long batch of non-decided blocks - return em.world.GetLatestBlockIndex() < em.world.GetLowestBlockToDecide()+basiccheck.MaxBlockVotesPerEvent*3 -} - -func (em *Emitter) skipLlrEpochVote() bool { - if em.neverSkipLlrVote() { - return false - } - // poor validators vote if we have a long batch of non-decided epochs - if em.epoch > em.world.GetLowestEpochToDecide()+2 { - return false - } - // otherwise, poor validators have a small chance to vote - return rand.Intn(30) != 0 -} - -func (em *Emitter) isEpochValidator(epoch idx.Epoch) bool { - es := em.world.GetHistoryEpochState(epoch) - if es == nil { - return false - } - - _, ok := es.ValidatorProfiles[em.config.Validator.ID] - return ok -} diff --git a/evm/go-x1/gossip/emitter/emitter_test.go b/evm/go-x1/gossip/emitter/emitter_test.go deleted file mode 100644 index 4421746..0000000 --- a/evm/go-x1/gossip/emitter/emitter_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package emitter - -import ( - "math/big" - "testing" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/gossip/emitter/mock" - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/utils/txtime" - "github.com/Fantom-foundation/go-opera/vecmt" -) - -//go:generate go run github.com/golang/mock/mockgen -package=mock -destination=mock/world.go github.com/Fantom-foundation/go-opera/gossip/emitter External,TxPool,TxSigner,Signer - -func TestEmitter(t *testing.T) { - cfg := DefaultConfig() - gValidators := makefakegenesis.GetFakeValidators(3) - vv := pos.NewBuilder() - for _, v := range gValidators { - vv.Set(v.ID, pos.Weight(1)) - } - validators := vv.Build() - cfg.Validator.ID = gValidators[0].ID - - ctrl := gomock.NewController(t) - external := mock.NewMockExternal(ctrl) - txPool := mock.NewMockTxPool(ctrl) - signer := mock.NewMockSigner(ctrl) - txSigner := mock.NewMockTxSigner(ctrl) - - external.EXPECT().Lock(). - AnyTimes() - external.EXPECT().Unlock(). - AnyTimes() - external.EXPECT().DagIndex(). - Return((*vecmt.Index)(nil)). - AnyTimes() - external.EXPECT().IsSynced(). - Return(true). - AnyTimes() - external.EXPECT().PeersNum(). - Return(int(3)). - AnyTimes() - external.EXPECT().StateDB(). - Return(nil). - AnyTimes() - - em := NewEmitter(cfg, World{ - External: external, - TxPool: txPool, - Signer: signer, - TxSigner: txSigner, - }) - - t.Run("init", func(t *testing.T) { - external.EXPECT().GetRules(). - Return(opera.FakeNetRules()). - AnyTimes() - - external.EXPECT().GetEpochValidators(). - Return(validators, idx.Epoch(1)). - AnyTimes() - - external.EXPECT().GetLastEvent(idx.Epoch(1), cfg.Validator.ID). - Return((*hash.Event)(nil)). - AnyTimes() - - external.EXPECT().GetGenesisTime(). - Return(inter.Timestamp(uint64(time.Now().UnixNano()))). - AnyTimes() - - em.init() - }) - - t.Run("memorizeTxTimes", func(t *testing.T) { - txtime.Enabled = true - require := require.New(t) - tx1 := types.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), nil) - tx2 := types.NewTransaction(2, common.Address{}, big.NewInt(2), 2, big.NewInt(2), nil) - - external.EXPECT().IsBusy(). - Return(true). - AnyTimes() - - txtime.Saw(tx1.Hash(), time.Unix(1, 0)) - - require.Equal(time.Unix(1, 0), txtime.Of(tx1.Hash())) - txtime.Saw(tx1.Hash(), time.Unix(2, 0)) - require.Equal(time.Unix(1, 0), txtime.Of(tx1.Hash())) - txtime.Validated(tx1.Hash(), time.Unix(2, 0)) - require.Equal(time.Unix(1, 0), txtime.Of(tx1.Hash())) - - // reversed order - txtime.Validated(tx2.Hash(), time.Unix(3, 0)) - txtime.Saw(tx2.Hash(), time.Unix(2, 0)) - - require.Equal(time.Unix(3, 0), txtime.Of(tx2.Hash())) - txtime.Saw(tx2.Hash(), time.Unix(3, 0)) - require.Equal(time.Unix(3, 0), txtime.Of(tx2.Hash())) - txtime.Validated(tx2.Hash(), time.Unix(3, 0)) - require.Equal(time.Unix(3, 0), txtime.Of(tx2.Hash())) - }) - - t.Run("tick", func(t *testing.T) { - em.tick() - }) -} diff --git a/evm/go-x1/gossip/emitter/hooks.go b/evm/go-x1/gossip/emitter/hooks.go deleted file mode 100644 index 974cc3d..0000000 --- a/evm/go-x1/gossip/emitter/hooks.go +++ /dev/null @@ -1,144 +0,0 @@ -package emitter - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/emitter/ancestor" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera/contracts/emitterdriver" - "github.com/Fantom-foundation/go-opera/utils" - "github.com/Fantom-foundation/go-opera/utils/adapters/vecmt2dagidx" -) - -// OnNewEpoch should be called after each epoch change, and on startup -func (em *Emitter) OnNewEpoch(newValidators *pos.Validators, newEpoch idx.Epoch) { - em.maxParents = em.config.MaxParents - rules := em.world.GetRules() - if em.maxParents == 0 { - em.maxParents = rules.Dag.MaxParents - } - if em.maxParents > rules.Dag.MaxParents { - em.maxParents = rules.Dag.MaxParents - } - if em.validators != nil && em.isValidator() && !em.validators.Exists(em.config.Validator.ID) && newValidators.Exists(em.config.Validator.ID) { - em.syncStatus.becameValidator = time.Now() - } - - em.validators, em.epoch = newValidators, newEpoch - - if !em.isValidator() { - return - } - em.prevEmittedAtTime = em.loadPrevEmitTime() - - em.originatedTxs.Clear() - em.pendingGas = 0 - - em.offlineValidators = make(map[idx.ValidatorID]bool) - em.challenges = make(map[idx.ValidatorID]time.Time) - em.expectedEmitIntervals = make(map[idx.ValidatorID]time.Duration) - em.stakeRatio = make(map[idx.ValidatorID]uint64) - - // get current adjustments from emitterdriver contract - statedb := em.world.StateDB() - var ( - extMinInterval time.Duration - extConfirmingInterval time.Duration - switchToFCIndexer bool - ) - if statedb != nil { - switchToFCIndexer = statedb.GetState(emitterdriver.ContractAddress, utils.U64to256(0)) != (common.Hash{0}) - extMinInterval = time.Duration(statedb.GetState(emitterdriver.ContractAddress, utils.U64to256(1)).Big().Uint64()) - extConfirmingInterval = time.Duration(statedb.GetState(emitterdriver.ContractAddress, utils.U64to256(2)).Big().Uint64()) - } - if extMinInterval == 0 { - extMinInterval = em.config.EmitIntervals.Min - } - if extConfirmingInterval == 0 { - extConfirmingInterval = em.config.EmitIntervals.Confirming - } - - // sanity check to ensure that durations aren't too small/large - em.intervals.Min = maxDuration(minDuration(em.config.EmitIntervals.Min*20, extMinInterval), em.config.EmitIntervals.Min/4) - em.globalConfirmingInterval = maxDuration(minDuration(em.config.EmitIntervals.Confirming*20, extConfirmingInterval), em.config.EmitIntervals.Confirming/4) - em.recountConfirmingIntervals(newValidators) - - if switchToFCIndexer { - em.quorumIndexer = nil - em.fcIndexer = ancestor.NewFCIndexer(newValidators, em.world.DagIndex(), em.config.Validator.ID) - } else { - em.quorumIndexer = ancestor.NewQuorumIndexer(newValidators, vecmt2dagidx.Wrap(em.world.DagIndex()), - func(median, current, update idx.Event, validatorIdx idx.Validator) ancestor.Metric { - return updMetric(median, current, update, validatorIdx, newValidators) - }) - em.fcIndexer = nil - } - em.quorumIndexer = ancestor.NewQuorumIndexer(newValidators, vecmt2dagidx.Wrap(em.world.DagIndex()), - func(median, current, update idx.Event, validatorIdx idx.Validator) ancestor.Metric { - return updMetric(median, current, update, validatorIdx, newValidators) - }) - em.payloadIndexer = ancestor.NewPayloadIndexer(PayloadIndexerSize) -} - -// OnEventConnected tracks new events -func (em *Emitter) OnEventConnected(e inter.EventPayloadI) { - if !em.isValidator() { - return - } - if em.fcIndexer != nil { - em.fcIndexer.ProcessEvent(e) - } else if em.quorumIndexer != nil { - em.quorumIndexer.ProcessEvent(e, e.Creator() == em.config.Validator.ID) - } - em.payloadIndexer.ProcessEvent(e, ancestor.Metric(e.Txs().Len())) - for _, tx := range e.Txs() { - addr, _ := types.Sender(em.world.TxSigner, tx) - em.originatedTxs.Inc(addr) - } - em.pendingGas += e.GasPowerUsed() - if e.Creator() == em.config.Validator.ID && em.syncStatus.prevLocalEmittedID != e.ID() { - // event was emitted by me on another instance - em.onNewExternalEvent(e) - } - // if there was any challenge, erase it - delete(em.challenges, e.Creator()) - // mark validator as online - delete(em.offlineValidators, e.Creator()) -} - -func (em *Emitter) OnEventConfirmed(he inter.EventI) { - if !em.isValidator() { - return - } - if em.pendingGas > he.GasPowerUsed() { - em.pendingGas -= he.GasPowerUsed() - } else { - em.pendingGas = 0 - } - if he.AnyTxs() { - e := em.world.GetEventPayload(he.ID()) - for _, tx := range e.Txs() { - addr, _ := types.Sender(em.world.TxSigner, tx) - em.originatedTxs.Dec(addr) - } - } -} - -func minDuration(a, b time.Duration) time.Duration { - if a < b { - return a - } - return b -} - -func maxDuration(a, b time.Duration) time.Duration { - if a > b { - return a - } - return b -} diff --git a/evm/go-x1/gossip/emitter/mock/world.go b/evm/go-x1/gossip/emitter/mock/world.go deleted file mode 100644 index 6c51c85..0000000 --- a/evm/go-x1/gossip/emitter/mock/world.go +++ /dev/null @@ -1,620 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Fantom-foundation/go-opera/gossip/emitter (interfaces: External,TxPool,TxSigner,Signer) - -// Package mock is a generated GoMock package. -package mock - -import ( - big "math/big" - reflect "reflect" - - inter "github.com/Fantom-foundation/go-opera/inter" - iblockproc "github.com/Fantom-foundation/go-opera/inter/iblockproc" - validatorpk "github.com/Fantom-foundation/go-opera/inter/validatorpk" - opera "github.com/Fantom-foundation/go-opera/opera" - vecmt "github.com/Fantom-foundation/go-opera/vecmt" - hash "github.com/Fantom-foundation/lachesis-base/hash" - idx "github.com/Fantom-foundation/lachesis-base/inter/idx" - pos "github.com/Fantom-foundation/lachesis-base/inter/pos" - common "github.com/ethereum/go-ethereum/common" - state "github.com/ethereum/go-ethereum/core/state" - types "github.com/ethereum/go-ethereum/core/types" - gomock "github.com/golang/mock/gomock" -) - -// MockExternal is a mock of External interface. -type MockExternal struct { - ctrl *gomock.Controller - recorder *MockExternalMockRecorder -} - -// MockExternalMockRecorder is the mock recorder for MockExternal. -type MockExternalMockRecorder struct { - mock *MockExternal -} - -// NewMockExternal creates a new mock instance. -func NewMockExternal(ctrl *gomock.Controller) *MockExternal { - mock := &MockExternal{ctrl: ctrl} - mock.recorder = &MockExternalMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockExternal) EXPECT() *MockExternalMockRecorder { - return m.recorder -} - -// Broadcast mocks base method. -func (m *MockExternal) Broadcast(arg0 *inter.EventPayload) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Broadcast", arg0) -} - -// Broadcast indicates an expected call of Broadcast. -func (mr *MockExternalMockRecorder) Broadcast(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Broadcast", reflect.TypeOf((*MockExternal)(nil).Broadcast), arg0) -} - -// Build mocks base method. -func (m *MockExternal) Build(arg0 *inter.MutableEventPayload, arg1 func()) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Build", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// Build indicates an expected call of Build. -func (mr *MockExternalMockRecorder) Build(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Build", reflect.TypeOf((*MockExternal)(nil).Build), arg0, arg1) -} - -// Check mocks base method. -func (m *MockExternal) Check(arg0 *inter.EventPayload, arg1 inter.Events) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Check", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// Check indicates an expected call of Check. -func (mr *MockExternalMockRecorder) Check(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Check", reflect.TypeOf((*MockExternal)(nil).Check), arg0, arg1) -} - -// DagIndex mocks base method. -func (m *MockExternal) DagIndex() *vecmt.Index { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DagIndex") - ret0, _ := ret[0].(*vecmt.Index) - return ret0 -} - -// DagIndex indicates an expected call of DagIndex. -func (mr *MockExternalMockRecorder) DagIndex() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DagIndex", reflect.TypeOf((*MockExternal)(nil).DagIndex)) -} - -// GetBlockEpoch mocks base method. -func (m *MockExternal) GetBlockEpoch(arg0 idx.Block) idx.Epoch { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockEpoch", arg0) - ret0, _ := ret[0].(idx.Epoch) - return ret0 -} - -// GetBlockEpoch indicates an expected call of GetBlockEpoch. -func (mr *MockExternalMockRecorder) GetBlockEpoch(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockEpoch", reflect.TypeOf((*MockExternal)(nil).GetBlockEpoch), arg0) -} - -// GetBlockRecordHash mocks base method. -func (m *MockExternal) GetBlockRecordHash(arg0 idx.Block) *hash.Hash { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockRecordHash", arg0) - ret0, _ := ret[0].(*hash.Hash) - return ret0 -} - -// GetBlockRecordHash indicates an expected call of GetBlockRecordHash. -func (mr *MockExternalMockRecorder) GetBlockRecordHash(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockRecordHash", reflect.TypeOf((*MockExternal)(nil).GetBlockRecordHash), arg0) -} - -// GetEpochRecordHash mocks base method. -func (m *MockExternal) GetEpochRecordHash(arg0 idx.Epoch) *hash.Hash { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEpochRecordHash", arg0) - ret0, _ := ret[0].(*hash.Hash) - return ret0 -} - -// GetEpochRecordHash indicates an expected call of GetEpochRecordHash. -func (mr *MockExternalMockRecorder) GetEpochRecordHash(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEpochRecordHash", reflect.TypeOf((*MockExternal)(nil).GetEpochRecordHash), arg0) -} - -// GetEpochValidators mocks base method. -func (m *MockExternal) GetEpochValidators() (*pos.Validators, idx.Epoch) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEpochValidators") - ret0, _ := ret[0].(*pos.Validators) - ret1, _ := ret[1].(idx.Epoch) - return ret0, ret1 -} - -// GetEpochValidators indicates an expected call of GetEpochValidators. -func (mr *MockExternalMockRecorder) GetEpochValidators() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEpochValidators", reflect.TypeOf((*MockExternal)(nil).GetEpochValidators)) -} - -// GetEvent mocks base method. -func (m *MockExternal) GetEvent(arg0 hash.Event) *inter.Event { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEvent", arg0) - ret0, _ := ret[0].(*inter.Event) - return ret0 -} - -// GetEvent indicates an expected call of GetEvent. -func (mr *MockExternalMockRecorder) GetEvent(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEvent", reflect.TypeOf((*MockExternal)(nil).GetEvent), arg0) -} - -// GetEventPayload mocks base method. -func (m *MockExternal) GetEventPayload(arg0 hash.Event) *inter.EventPayload { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEventPayload", arg0) - ret0, _ := ret[0].(*inter.EventPayload) - return ret0 -} - -// GetEventPayload indicates an expected call of GetEventPayload. -func (mr *MockExternalMockRecorder) GetEventPayload(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEventPayload", reflect.TypeOf((*MockExternal)(nil).GetEventPayload), arg0) -} - -// GetGenesisTime mocks base method. -func (m *MockExternal) GetGenesisTime() inter.Timestamp { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetGenesisTime") - ret0, _ := ret[0].(inter.Timestamp) - return ret0 -} - -// GetGenesisTime indicates an expected call of GetGenesisTime. -func (mr *MockExternalMockRecorder) GetGenesisTime() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGenesisTime", reflect.TypeOf((*MockExternal)(nil).GetGenesisTime)) -} - -// GetHeads mocks base method. -func (m *MockExternal) GetHeads(arg0 idx.Epoch) hash.Events { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetHeads", arg0) - ret0, _ := ret[0].(hash.Events) - return ret0 -} - -// GetHeads indicates an expected call of GetHeads. -func (mr *MockExternalMockRecorder) GetHeads(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHeads", reflect.TypeOf((*MockExternal)(nil).GetHeads), arg0) -} - -// GetHistoryEpochState mocks base method. -func (m *MockExternal) GetHistoryEpochState(arg0 idx.Epoch) *iblockproc.EpochState { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetHistoryEpochState", arg0) - ret0, _ := ret[0].(*iblockproc.EpochState) - return ret0 -} - -// GetHistoryEpochState indicates an expected call of GetHistoryEpochState. -func (mr *MockExternalMockRecorder) GetHistoryEpochState(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHistoryEpochState", reflect.TypeOf((*MockExternal)(nil).GetHistoryEpochState), arg0) -} - -// GetLastBV mocks base method. -func (m *MockExternal) GetLastBV(arg0 idx.ValidatorID) *idx.Block { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLastBV", arg0) - ret0, _ := ret[0].(*idx.Block) - return ret0 -} - -// GetLastBV indicates an expected call of GetLastBV. -func (mr *MockExternalMockRecorder) GetLastBV(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastBV", reflect.TypeOf((*MockExternal)(nil).GetLastBV), arg0) -} - -// GetLastEV mocks base method. -func (m *MockExternal) GetLastEV(arg0 idx.ValidatorID) *idx.Epoch { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLastEV", arg0) - ret0, _ := ret[0].(*idx.Epoch) - return ret0 -} - -// GetLastEV indicates an expected call of GetLastEV. -func (mr *MockExternalMockRecorder) GetLastEV(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastEV", reflect.TypeOf((*MockExternal)(nil).GetLastEV), arg0) -} - -// GetLastEvent mocks base method. -func (m *MockExternal) GetLastEvent(arg0 idx.Epoch, arg1 idx.ValidatorID) *hash.Event { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLastEvent", arg0, arg1) - ret0, _ := ret[0].(*hash.Event) - return ret0 -} - -// GetLastEvent indicates an expected call of GetLastEvent. -func (mr *MockExternalMockRecorder) GetLastEvent(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastEvent", reflect.TypeOf((*MockExternal)(nil).GetLastEvent), arg0, arg1) -} - -// GetLatestBlockIndex mocks base method. -func (m *MockExternal) GetLatestBlockIndex() idx.Block { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLatestBlockIndex") - ret0, _ := ret[0].(idx.Block) - return ret0 -} - -// GetLatestBlockIndex indicates an expected call of GetLatestBlockIndex. -func (mr *MockExternalMockRecorder) GetLatestBlockIndex() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestBlockIndex", reflect.TypeOf((*MockExternal)(nil).GetLatestBlockIndex)) -} - -// GetLowestBlockToDecide mocks base method. -func (m *MockExternal) GetLowestBlockToDecide() idx.Block { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLowestBlockToDecide") - ret0, _ := ret[0].(idx.Block) - return ret0 -} - -// GetLowestBlockToDecide indicates an expected call of GetLowestBlockToDecide. -func (mr *MockExternalMockRecorder) GetLowestBlockToDecide() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLowestBlockToDecide", reflect.TypeOf((*MockExternal)(nil).GetLowestBlockToDecide)) -} - -// GetLowestEpochToDecide mocks base method. -func (m *MockExternal) GetLowestEpochToDecide() idx.Epoch { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLowestEpochToDecide") - ret0, _ := ret[0].(idx.Epoch) - return ret0 -} - -// GetLowestEpochToDecide indicates an expected call of GetLowestEpochToDecide. -func (mr *MockExternalMockRecorder) GetLowestEpochToDecide() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLowestEpochToDecide", reflect.TypeOf((*MockExternal)(nil).GetLowestEpochToDecide)) -} - -// GetRules mocks base method. -func (m *MockExternal) GetRules() opera.Rules { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRules") - ret0, _ := ret[0].(opera.Rules) - return ret0 -} - -// GetRules indicates an expected call of GetRules. -func (mr *MockExternalMockRecorder) GetRules() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRules", reflect.TypeOf((*MockExternal)(nil).GetRules)) -} - -// IsBusy mocks base method. -func (m *MockExternal) IsBusy() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsBusy") - ret0, _ := ret[0].(bool) - return ret0 -} - -// IsBusy indicates an expected call of IsBusy. -func (mr *MockExternalMockRecorder) IsBusy() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBusy", reflect.TypeOf((*MockExternal)(nil).IsBusy)) -} - -// IsSynced mocks base method. -func (m *MockExternal) IsSynced() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsSynced") - ret0, _ := ret[0].(bool) - return ret0 -} - -// IsSynced indicates an expected call of IsSynced. -func (mr *MockExternalMockRecorder) IsSynced() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSynced", reflect.TypeOf((*MockExternal)(nil).IsSynced)) -} - -// Lock mocks base method. -func (m *MockExternal) Lock() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Lock") -} - -// Lock indicates an expected call of Lock. -func (mr *MockExternalMockRecorder) Lock() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lock", reflect.TypeOf((*MockExternal)(nil).Lock)) -} - -// PeersNum mocks base method. -func (m *MockExternal) PeersNum() int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PeersNum") - ret0, _ := ret[0].(int) - return ret0 -} - -// PeersNum indicates an expected call of PeersNum. -func (mr *MockExternalMockRecorder) PeersNum() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeersNum", reflect.TypeOf((*MockExternal)(nil).PeersNum)) -} - -// Process mocks base method. -func (m *MockExternal) Process(arg0 *inter.EventPayload) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Process", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Process indicates an expected call of Process. -func (mr *MockExternalMockRecorder) Process(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Process", reflect.TypeOf((*MockExternal)(nil).Process), arg0) -} - -// StateDB mocks base method. -func (m *MockExternal) StateDB() *state.StateDB { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateDB") - ret0, _ := ret[0].(*state.StateDB) - return ret0 -} - -// StateDB indicates an expected call of StateDB. -func (mr *MockExternalMockRecorder) StateDB() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateDB", reflect.TypeOf((*MockExternal)(nil).StateDB)) -} - -// Unlock mocks base method. -func (m *MockExternal) Unlock() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Unlock") -} - -// Unlock indicates an expected call of Unlock. -func (mr *MockExternalMockRecorder) Unlock() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockExternal)(nil).Unlock)) -} - -// MockTxPool is a mock of TxPool interface. -type MockTxPool struct { - ctrl *gomock.Controller - recorder *MockTxPoolMockRecorder -} - -// MockTxPoolMockRecorder is the mock recorder for MockTxPool. -type MockTxPoolMockRecorder struct { - mock *MockTxPool -} - -// NewMockTxPool creates a new mock instance. -func NewMockTxPool(ctrl *gomock.Controller) *MockTxPool { - mock := &MockTxPool{ctrl: ctrl} - mock.recorder = &MockTxPoolMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockTxPool) EXPECT() *MockTxPoolMockRecorder { - return m.recorder -} - -// Count mocks base method. -func (m *MockTxPool) Count() int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Count") - ret0, _ := ret[0].(int) - return ret0 -} - -// Count indicates an expected call of Count. -func (mr *MockTxPoolMockRecorder) Count() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Count", reflect.TypeOf((*MockTxPool)(nil).Count)) -} - -// Has mocks base method. -func (m *MockTxPool) Has(arg0 common.Hash) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Has", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// Has indicates an expected call of Has. -func (mr *MockTxPoolMockRecorder) Has(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockTxPool)(nil).Has), arg0) -} - -// Pending mocks base method. -func (m *MockTxPool) Pending(arg0 bool) (map[common.Address]types.Transactions, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Pending", arg0) - ret0, _ := ret[0].(map[common.Address]types.Transactions) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Pending indicates an expected call of Pending. -func (mr *MockTxPoolMockRecorder) Pending(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pending", reflect.TypeOf((*MockTxPool)(nil).Pending), arg0) -} - -// MockTxSigner is a mock of TxSigner interface. -type MockTxSigner struct { - ctrl *gomock.Controller - recorder *MockTxSignerMockRecorder -} - -// MockTxSignerMockRecorder is the mock recorder for MockTxSigner. -type MockTxSignerMockRecorder struct { - mock *MockTxSigner -} - -// NewMockTxSigner creates a new mock instance. -func NewMockTxSigner(ctrl *gomock.Controller) *MockTxSigner { - mock := &MockTxSigner{ctrl: ctrl} - mock.recorder = &MockTxSignerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockTxSigner) EXPECT() *MockTxSignerMockRecorder { - return m.recorder -} - -// ChainID mocks base method. -func (m *MockTxSigner) ChainID() *big.Int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ChainID") - ret0, _ := ret[0].(*big.Int) - return ret0 -} - -// ChainID indicates an expected call of ChainID. -func (mr *MockTxSignerMockRecorder) ChainID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainID", reflect.TypeOf((*MockTxSigner)(nil).ChainID)) -} - -// Equal mocks base method. -func (m *MockTxSigner) Equal(arg0 types.Signer) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Equal", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// Equal indicates an expected call of Equal. -func (mr *MockTxSignerMockRecorder) Equal(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Equal", reflect.TypeOf((*MockTxSigner)(nil).Equal), arg0) -} - -// Hash mocks base method. -func (m *MockTxSigner) Hash(arg0 *types.Transaction) common.Hash { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Hash", arg0) - ret0, _ := ret[0].(common.Hash) - return ret0 -} - -// Hash indicates an expected call of Hash. -func (mr *MockTxSignerMockRecorder) Hash(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Hash", reflect.TypeOf((*MockTxSigner)(nil).Hash), arg0) -} - -// Sender mocks base method. -func (m *MockTxSigner) Sender(arg0 *types.Transaction) (common.Address, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Sender", arg0) - ret0, _ := ret[0].(common.Address) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Sender indicates an expected call of Sender. -func (mr *MockTxSignerMockRecorder) Sender(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sender", reflect.TypeOf((*MockTxSigner)(nil).Sender), arg0) -} - -// SignatureValues mocks base method. -func (m *MockTxSigner) SignatureValues(arg0 *types.Transaction, arg1 []byte) (*big.Int, *big.Int, *big.Int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SignatureValues", arg0, arg1) - ret0, _ := ret[0].(*big.Int) - ret1, _ := ret[1].(*big.Int) - ret2, _ := ret[2].(*big.Int) - ret3, _ := ret[3].(error) - return ret0, ret1, ret2, ret3 -} - -// SignatureValues indicates an expected call of SignatureValues. -func (mr *MockTxSignerMockRecorder) SignatureValues(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignatureValues", reflect.TypeOf((*MockTxSigner)(nil).SignatureValues), arg0, arg1) -} - -// MockSigner is a mock of Signer interface. -type MockSigner struct { - ctrl *gomock.Controller - recorder *MockSignerMockRecorder -} - -// MockSignerMockRecorder is the mock recorder for MockSigner. -type MockSignerMockRecorder struct { - mock *MockSigner -} - -// NewMockSigner creates a new mock instance. -func NewMockSigner(ctrl *gomock.Controller) *MockSigner { - mock := &MockSigner{ctrl: ctrl} - mock.recorder = &MockSignerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockSigner) EXPECT() *MockSignerMockRecorder { - return m.recorder -} - -// Sign mocks base method. -func (m *MockSigner) Sign(arg0 validatorpk.PubKey, arg1 []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Sign", arg0, arg1) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Sign indicates an expected call of Sign. -func (mr *MockSignerMockRecorder) Sign(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sign", reflect.TypeOf((*MockSigner)(nil).Sign), arg0, arg1) -} diff --git a/evm/go-x1/gossip/emitter/originatedtxs/txs_ring_buffer.go b/evm/go-x1/gossip/emitter/originatedtxs/txs_ring_buffer.go deleted file mode 100644 index 981e000..0000000 --- a/evm/go-x1/gossip/emitter/originatedtxs/txs_ring_buffer.go +++ /dev/null @@ -1,58 +0,0 @@ -package originatedtxs - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/hashicorp/golang-lru/simplelru" -) - -type Buffer struct { - senderCount *simplelru.LRU // sender address -> number of transactions -} - -func New(maxAddresses int) *Buffer { - ring := &Buffer{} - ring.senderCount, _ = simplelru.NewLRU(maxAddresses, nil) - return ring -} - -// Inc is not safe for concurrent use -func (ring *Buffer) Inc(sender common.Address) { - cur, ok := ring.senderCount.Peek(sender) - if ok { - ring.senderCount.Add(sender, cur.(int)+1) - } else { - ring.senderCount.Add(sender, int(1)) - } -} - -// Dec is not safe for concurrent use -func (ring *Buffer) Dec(sender common.Address) { - cur, ok := ring.senderCount.Peek(sender) - if !ok { - return - } - if cur.(int) <= 1 { - ring.senderCount.Remove(sender) - } else { - ring.senderCount.Add(sender, cur.(int)-1) - } -} - -// Clear is not safe for concurrent use -func (ring *Buffer) Clear() { - ring.senderCount.Purge() -} - -// TotalOf is not safe for concurrent use -func (ring *Buffer) TotalOf(sender common.Address) int { - cur, ok := ring.senderCount.Get(sender) - if !ok { - return 0 - } - return cur.(int) -} - -// Empty is not safe for concurrent use -func (ring *Buffer) Empty() bool { - return ring.senderCount.Len() == 0 -} diff --git a/evm/go-x1/gossip/emitter/parents.go b/evm/go-x1/gossip/emitter/parents.go deleted file mode 100644 index 9fea2b4..0000000 --- a/evm/go-x1/gossip/emitter/parents.go +++ /dev/null @@ -1,55 +0,0 @@ -package emitter - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/emitter/ancestor" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -// buildSearchStrategies returns a strategy for each parent search -func (em *Emitter) buildSearchStrategies(maxParents idx.Event) []ancestor.SearchStrategy { - strategies := make([]ancestor.SearchStrategy, 0, maxParents) - if maxParents == 0 { - return strategies - } - payloadStrategy := em.payloadIndexer.SearchStrategy() - for idx.Event(len(strategies)) < 1 { - strategies = append(strategies, payloadStrategy) - } - randStrategy := ancestor.NewRandomStrategy(nil) - for idx.Event(len(strategies)) < maxParents/2 { - strategies = append(strategies, randStrategy) - } - if em.fcIndexer != nil { - quorumStrategy := em.fcIndexer.SearchStrategy() - for idx.Event(len(strategies)) < maxParents { - strategies = append(strategies, quorumStrategy) - } - } else if em.quorumIndexer != nil { - quorumStrategy := em.quorumIndexer.SearchStrategy() - for idx.Event(len(strategies)) < maxParents { - strategies = append(strategies, quorumStrategy) - } - } - return strategies -} - -// chooseParents selects an "optimal" parents set for the validator -func (em *Emitter) chooseParents(epoch idx.Epoch, myValidatorID idx.ValidatorID) (*hash.Event, hash.Events, bool) { - selfParent := em.world.GetLastEvent(epoch, myValidatorID) - heads := em.world.GetHeads(epoch) // events with no descendants - - if selfParent != nil && len(em.world.DagIndex().NoCheaters(selfParent, hash.Events{*selfParent})) == 0 { - em.Periodic.Error(time.Second, "Events emitting isn't allowed due to the doublesign", "validator", myValidatorID) - return nil, nil, false - } - - var parents hash.Events - if selfParent != nil { - parents = hash.Events{*selfParent} - } - parents = ancestor.ChooseParents(parents, heads, em.buildSearchStrategies(em.maxParents-idx.Event(len(parents)))) - return selfParent, parents, true -} diff --git a/evm/go-x1/gossip/emitter/piecefuncs.go b/evm/go-x1/gossip/emitter/piecefuncs.go deleted file mode 100644 index c6d9d8a..0000000 --- a/evm/go-x1/gossip/emitter/piecefuncs.go +++ /dev/null @@ -1,130 +0,0 @@ -package emitter - -import ( - "github.com/Fantom-foundation/lachesis-base/emitter/ancestor" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/piecefunc" -) - -var ( - // confirmingEmitIntervalF is a piecewise function for validator confirming internal depending on a stake amount before him - confirmingEmitIntervalF = piecefunc.NewFunc([]piecefunc.Dot{ - { - X: 0, - Y: 1.0 * piecefunc.DecimalUnit, - }, - { - X: 0.78 * piecefunc.DecimalUnit, - Y: 1.1 * piecefunc.DecimalUnit, - }, - { - X: 0.8 * piecefunc.DecimalUnit, - Y: 10.0 * piecefunc.DecimalUnit, - }, - { // validators >0.8 emit confirming events very rarely - X: 0.81 * piecefunc.DecimalUnit, - Y: 50.0 * piecefunc.DecimalUnit, - }, - { // validators >0.8 emit confirming events very rarely - X: 1.0 * piecefunc.DecimalUnit, - Y: 60.0 * piecefunc.DecimalUnit, - }, - }) - // scalarUpdMetricF is a piecewise function for validator's event metric diff depending on a number of newly observed events - scalarUpdMetricF = piecefunc.NewFunc([]piecefunc.Dot{ - { - X: 0, - Y: 0, - }, - { // first observed event gives a major metric diff - X: 1.0 * piecefunc.DecimalUnit, - Y: 0.66 * piecefunc.DecimalUnit, - }, - { // second observed event gives a minor diff - X: 2.0 * piecefunc.DecimalUnit, - Y: 0.8 * piecefunc.DecimalUnit, - }, - { // other observed event give only a subtle diff - X: 8.0 * piecefunc.DecimalUnit, - Y: 0.99 * piecefunc.DecimalUnit, - }, - { - X: 100.0 * piecefunc.DecimalUnit, - Y: 0.999 * piecefunc.DecimalUnit, - }, - { - X: 10000.0 * piecefunc.DecimalUnit, - Y: 0.9999 * piecefunc.DecimalUnit, - }, - }) - // eventMetricF is a piecewise function for event metric adjustment depending on a non-adjusted event metric - eventMetricF = piecefunc.NewFunc([]piecefunc.Dot{ - { // event metric is never zero - X: 0, - Y: 0.005 * piecefunc.DecimalUnit, - }, - { - X: 0.01 * piecefunc.DecimalUnit, - Y: 0.03 * piecefunc.DecimalUnit, - }, - { // if metric is below ~0.2, then validator shouldn't emit event unless waited very long - X: 0.2 * piecefunc.DecimalUnit, - Y: 0.05 * piecefunc.DecimalUnit, - }, - { - X: 0.3 * piecefunc.DecimalUnit, - Y: 0.22 * piecefunc.DecimalUnit, - }, - { // ~0.3-0.5 is an optimal metric to emit an event - X: 0.4 * piecefunc.DecimalUnit, - Y: 0.45 * piecefunc.DecimalUnit, - }, - { - X: 1.0 * piecefunc.DecimalUnit, - Y: 1.0 * piecefunc.DecimalUnit, - }, - }) - validatorsToOverheadF = piecefunc.NewFunc([]piecefunc.Dot{ - { - X: 0, - Y: 0, - }, - { - X: 70, - Y: 0.05 * piecefunc.DecimalUnit, - }, - { - X: 100, - Y: 0.1 * piecefunc.DecimalUnit, - }, - { - X: 120, - Y: 0.3 * piecefunc.DecimalUnit, - }, - { - X: 150, - Y: 0.5 * piecefunc.DecimalUnit, - }, - { - X: 200, - Y: 0.8 * piecefunc.DecimalUnit, - }, - { - X: 220, - Y: 0.95 * piecefunc.DecimalUnit, - }, - { - X: 100000, - Y: 1.0 * piecefunc.DecimalUnit, - }, - }) - overheadF = func(validatorsNum idx.Validator, busyRate uint64) uint64 { - if busyRate > piecefunc.DecimalUnit { - busyRate = piecefunc.DecimalUnit - } - return validatorsToOverheadF(uint64(validatorsNum)) * busyRate / piecefunc.DecimalUnit - } - overheadAdjustedEventMetricF = func(validatorsNum idx.Validator, busyRate uint64, eventMetric ancestor.Metric) ancestor.Metric { - return ancestor.Metric(piecefunc.DecimalUnit-overheadF(validatorsNum, busyRate)) * eventMetric / piecefunc.DecimalUnit - } -) diff --git a/evm/go-x1/gossip/emitter/prev_action_files.go b/evm/go-x1/gossip/emitter/prev_action_files.go deleted file mode 100644 index 8c8bbdf..0000000 --- a/evm/go-x1/gossip/emitter/prev_action_files.go +++ /dev/null @@ -1,91 +0,0 @@ -package emitter - -import ( - "io" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/log" - - "github.com/Fantom-foundation/go-opera/utils" -) - -var openPrevActionFile = utils.OpenFile - -func (em *Emitter) writeLastEmittedEventID(id hash.Event) { - if em.emittedEventFile == nil { - return - } - _, err := em.emittedEventFile.WriteAt(id.Bytes(), 0) - if err != nil { - log.Crit("Failed to write event file", "file", em.config.PrevEmittedEventFile.Path, "err", err) - } -} - -func (em *Emitter) readLastEmittedEventID() *hash.Event { - if em.emittedEventFile == nil { - return nil - } - buf := make([]byte, 32) - _, err := em.emittedEventFile.ReadAt(buf, 0) - if err != nil { - if err == io.EOF { - return nil - } - log.Crit("Failed to read event file", "file", em.config.PrevEmittedEventFile.Path, "err", err) - } - v := hash.BytesToEvent(buf) - return &v -} - -func (em *Emitter) writeLastEmittedBlockVotes(b idx.Block) { - if em.emittedBvsFile == nil { - return - } - _, err := em.emittedBvsFile.WriteAt(b.Bytes(), 0) - if err != nil { - log.Crit("Failed to write BVs file", "file", em.config.PrevBlockVotesFile.Path, "err", err) - } -} - -func (em *Emitter) readLastBlockVotes() *idx.Block { - if em.emittedBvsFile == nil { - return nil - } - buf := make([]byte, 8) - _, err := em.emittedBvsFile.ReadAt(buf, 0) - if err != nil { - if err == io.EOF { - return nil - } - log.Crit("Failed to read BVs file", "file", em.config.PrevBlockVotesFile.Path, "err", err) - } - v := idx.BytesToBlock(buf) - return &v -} - -func (em *Emitter) writeLastEmittedEpochVote(e idx.Epoch) { - if em.emittedEvFile == nil { - return - } - _, err := em.emittedEvFile.WriteAt(e.Bytes(), 0) - if err != nil { - log.Crit("Failed to write BVs file", "file", em.config.PrevEpochVoteFile.Path, "err", err) - } -} - -func (em *Emitter) readLastEpochVote() *idx.Epoch { - if em.emittedEvFile == nil { - return nil - } - buf := make([]byte, 4) - _, err := em.emittedEvFile.ReadAt(buf, 0) - if err != nil { - if err == io.EOF { - return nil - } - log.Crit("Failed to read EV file", "file", em.config.PrevEpochVoteFile.Path, "err", err) - } - v := idx.BytesToEpoch(buf) - return &v -} diff --git a/evm/go-x1/gossip/emitter/sync.go b/evm/go-x1/gossip/emitter/sync.go deleted file mode 100644 index bae98bf..0000000 --- a/evm/go-x1/gossip/emitter/sync.go +++ /dev/null @@ -1,79 +0,0 @@ -package emitter - -import ( - "fmt" - "time" - - "github.com/Fantom-foundation/lachesis-base/emitter/doublesign" - "github.com/Fantom-foundation/lachesis-base/hash" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/utils/errlock" -) - -type syncStatus struct { - startup time.Time - lastConnected time.Time - p2pSynced time.Time - prevLocalEmittedID hash.Event - externalSelfEventCreated time.Time - externalSelfEventDetected time.Time - becameValidator time.Time -} - -func (em *Emitter) onNewExternalEvent(e inter.EventPayloadI) { - em.syncStatus.externalSelfEventDetected = time.Now() - em.syncStatus.externalSelfEventCreated = e.CreationTime().Time() - status := em.currentSyncStatus() - if doublesign.DetectParallelInstance(status, em.config.EmitIntervals.ParallelInstanceProtection) { - passedSinceEvent := status.Since(status.ExternalSelfEventCreated) - reason := "Received a recent event (event id=%s) from this validator (validator ID=%d) which wasn't created on this node.\n" + - "This external event was created %s, %s ago at the time of this error.\n" + - "It might mean that a duplicating instance of the same validator is running simultaneously, which may eventually lead to a doublesign.\n" + - "The node was stopped by one of the doublesign protection heuristics.\n" + - "There's no guaranteed automatic protection against a doublesign, " + - "please always ensure that no more than one instance of the same validator is running." - errlock.Permanent(fmt.Errorf(reason, e.ID().String(), em.config.Validator.ID, e.CreationTime().Time().Local().String(), passedSinceEvent.String())) - panic("unreachable") - } -} - -func (em *Emitter) currentSyncStatus() doublesign.SyncStatus { - s := doublesign.SyncStatus{ - Now: time.Now(), - PeersNum: em.world.PeersNum(), - Startup: em.syncStatus.startup, - LastConnected: em.syncStatus.lastConnected, - ExternalSelfEventCreated: em.syncStatus.externalSelfEventCreated, - ExternalSelfEventDetected: em.syncStatus.externalSelfEventDetected, - BecameValidator: em.syncStatus.becameValidator, - } - if em.world.IsSynced() { - s.P2PSynced = em.syncStatus.p2pSynced - } - prevEmitted := em.readLastEmittedEventID() - if prevEmitted != nil && (em.world.GetEvent(*prevEmitted) == nil && em.epoch <= prevEmitted.Epoch()) { - s.P2PSynced = time.Time{} - } - return s -} - -func (em *Emitter) isSyncedToEmit() (time.Duration, error) { - if em.intervals.DoublesignProtection == 0 { - return 0, nil // protection disabled - } - return doublesign.SyncedToEmit(em.currentSyncStatus(), em.intervals.DoublesignProtection) -} - -func (em *Emitter) logSyncStatus(wait time.Duration, syncErr error) bool { - if syncErr == nil { - return true - } - - if wait == 0 { - em.Periodic.Info(7*time.Second, "Emitting is paused", "reason", syncErr) - } else { - em.Periodic.Info(7*time.Second, "Emitting is paused", "reason", syncErr, "wait", wait) - } - return false -} diff --git a/evm/go-x1/gossip/emitter/txs.go b/evm/go-x1/gossip/emitter/txs.go deleted file mode 100644 index c2bc585..0000000 --- a/evm/go-x1/gossip/emitter/txs.go +++ /dev/null @@ -1,174 +0,0 @@ -package emitter - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/eventcheck/epochcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/gaspowercheck" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/utils" - "github.com/Fantom-foundation/go-opera/utils/txtime" -) - -const ( - TxTurnPeriod = 8 * time.Second - TxTurnPeriodLatency = 1 * time.Second - TxTurnNonces = 32 -) - -func max64(a, b uint64) uint64 { - if a > b { - return a - } - return b -} - -func (em *Emitter) maxGasPowerToUse(e *inter.MutableEventPayload) uint64 { - rules := em.world.GetRules() - maxGasToUse := rules.Economy.Gas.MaxEventGas - if maxGasToUse > e.GasPowerLeft().Min() { - maxGasToUse = e.GasPowerLeft().Min() - } - // Smooth TPS if power isn't big - if em.config.LimitedTpsThreshold > em.config.NoTxsThreshold { - upperThreshold := em.config.LimitedTpsThreshold - downThreshold := em.config.NoTxsThreshold - - estimatedAlloc := gaspowercheck.CalcValidatorGasPower(e, e.CreationTime(), e.MedianTime(), 0, em.validators, gaspowercheck.Config{ - Idx: inter.LongTermGas, - AllocPerSec: rules.Economy.LongGasPower.AllocPerSec * 4 / 5, - MaxAllocPeriod: inter.Timestamp(time.Minute), - MinEnsuredAlloc: 0, - StartupAllocPeriod: 0, - MinStartupGas: 0, - }) - - gasPowerLeft := e.GasPowerLeft().Min() + estimatedAlloc - if gasPowerLeft < downThreshold { - return 0 - } - newGasPowerLeft := uint64(0) - if gasPowerLeft > maxGasToUse { - newGasPowerLeft = gasPowerLeft - maxGasToUse - } - - var x1, x2 = newGasPowerLeft, gasPowerLeft - if x1 < downThreshold { - x1 = downThreshold - } - if x2 > upperThreshold { - x2 = upperThreshold - } - trespassingPart := uint64(0) - if x2 > x1 { - trespassingPart = x2 - x1 - } - healthyPart := uint64(0) - if gasPowerLeft > x2 { - healthyPart = gasPowerLeft - x2 - } - - smoothGasToUse := healthyPart + trespassingPart/2 - if maxGasToUse > smoothGasToUse { - maxGasToUse = smoothGasToUse - } - } - // pendingGas should be below MaxBlockGas - { - maxPendingGas := max64(max64(rules.Blocks.MaxBlockGas/3, rules.Economy.Gas.MaxEventGas), 15000000) - if maxPendingGas <= em.pendingGas { - return 0 - } - if maxPendingGas < em.pendingGas+maxGasToUse { - maxGasToUse = maxPendingGas - em.pendingGas - } - } - // No txs if power is low - { - threshold := em.config.NoTxsThreshold - if e.GasPowerLeft().Min() <= threshold { - return 0 - } else if e.GasPowerLeft().Min() < threshold+maxGasToUse { - maxGasToUse = e.GasPowerLeft().Min() - threshold - } - } - return maxGasToUse -} - -func getTxRoundIndex(now, txTime time.Time, validatorsNum idx.Validator) int { - passed := now.Sub(txTime) - if passed < 0 { - passed = 0 - } - return int((passed / TxTurnPeriod) % time.Duration(validatorsNum)) -} - -// safe for concurrent use -func (em *Emitter) isMyTxTurn(txHash common.Hash, sender common.Address, accountNonce uint64, now time.Time, validators *pos.Validators, me idx.ValidatorID, epoch idx.Epoch) bool { - txTime := txtime.Of(txHash) - - roundIndex := getTxRoundIndex(now, txTime, validators.Len()) - if roundIndex != getTxRoundIndex(now.Add(TxTurnPeriodLatency), txTime, validators.Len()) { - // round is about to change, avoid originating the transaction to avoid racing with another validator - return false - } - - roundsHash := hash.Of(sender.Bytes(), bigendian.Uint64ToBytes(accountNonce/TxTurnNonces), epoch.Bytes()) - rounds := utils.WeightedPermutation(roundIndex+1, validators.SortedWeights(), roundsHash) - return validators.GetID(idx.Validator(rounds[roundIndex])) == me -} - -func (em *Emitter) addTxs(e *inter.MutableEventPayload, sorted *types.TransactionsByPriceAndNonce) { - maxGasUsed := em.maxGasPowerToUse(e) - if maxGasUsed <= e.GasPowerUsed() { - return - } - - // sort transactions by price and nonce - rules := em.world.GetRules() - for tx := sorted.Peek(); tx != nil; tx = sorted.Peek() { - sender, _ := types.Sender(em.world.TxSigner, tx) - // check transaction epoch rules - if epochcheck.CheckTxs(types.Transactions{tx}, rules) != nil { - sorted.Pop() - continue - } - // check there's enough gas power to originate the transaction - if tx.Gas() >= e.GasPowerLeft().Min() || e.GasPowerUsed()+tx.Gas() >= maxGasUsed { - if params.TxGas >= e.GasPowerLeft().Min() || e.GasPowerUsed()+params.TxGas >= maxGasUsed { - // stop if cannot originate even an empty transaction - break - } - sorted.Pop() - continue - } - // check not conflicted with already originated txs (in any connected event) - if em.originatedTxs.TotalOf(sender) != 0 { - sorted.Pop() - continue - } - // my turn, i.e. try to not include the same tx simultaneously by different validators - if !em.isMyTxTurn(tx.Hash(), sender, tx.Nonce(), time.Now(), em.validators, e.Creator(), em.epoch) { - sorted.Pop() - continue - } - // check transaction is not outdated - if !em.world.TxPool.Has(tx.Hash()) { - sorted.Pop() - continue - } - // add - e.SetGasPowerUsed(e.GasPowerUsed() + tx.Gas()) - e.SetGasPowerLeft(e.GasPowerLeft().Sub(tx.Gas())) - e.SetTxs(append(e.Txs(), tx)) - sorted.Shift() - } -} diff --git a/evm/go-x1/gossip/emitter/validators.go b/evm/go-x1/gossip/emitter/validators.go deleted file mode 100644 index 0292c6e..0000000 --- a/evm/go-x1/gossip/emitter/validators.go +++ /dev/null @@ -1,66 +0,0 @@ -package emitter - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/utils/piecefunc" -) - -const ( - validatorChallenge = 4 * time.Second -) - -func (em *Emitter) recountConfirmingIntervals(validators *pos.Validators) { - // validators with lower stake should emit fewer events to reduce network load - // confirmingEmitInterval = piecefunc(totalStakeBeforeMe / totalStake) * MinEmitInterval - totalStakeBefore := pos.Weight(0) - for i, stake := range validators.SortedWeights() { - vid := validators.GetID(idx.Validator(i)) - // pos.Weight is uint32, so cast to uint64 to avoid an overflow - stakeRatio := uint64(totalStakeBefore) * uint64(piecefunc.DecimalUnit) / uint64(validators.TotalWeight()) - if !em.offlineValidators[vid] { - totalStakeBefore += stake - } - confirmingEmitIntervalRatio := confirmingEmitIntervalF(stakeRatio) - em.stakeRatio[vid] = stakeRatio - em.expectedEmitIntervals[vid] = time.Duration(piecefunc.Mul(uint64(em.globalConfirmingInterval), confirmingEmitIntervalRatio)) - } - em.intervals.Confirming = em.expectedEmitIntervals[em.config.Validator.ID] -} - -func (em *Emitter) recheckChallenges() { - if time.Since(em.prevRecheckedChallenges) < validatorChallenge/10 { - return - } - em.world.Lock() - defer em.world.Unlock() - now := time.Now() - if !em.idle() { - // give challenges to all the non-spare validators if network isn't idle - for _, vid := range em.validators.IDs() { - if em.offlineValidators[vid] { - continue - } - if _, ok := em.challenges[vid]; !ok { - em.challenges[vid] = now.Add(validatorChallenge + em.expectedEmitIntervals[vid]*4) - } - } - } else { - // erase all the challenges if network is idle - em.challenges = make(map[idx.ValidatorID]time.Time) - } - // check challenges - recount := false - for vid, challengeDeadline := range em.challenges { - if now.After(challengeDeadline) { - em.offlineValidators[vid] = true - recount = true - } - } - if recount { - em.recountConfirmingIntervals(em.validators) - } - em.prevRecheckedChallenges = now -} diff --git a/evm/go-x1/gossip/emitter/world.go b/evm/go-x1/gossip/emitter/world.go deleted file mode 100644 index 73a7d95..0000000 --- a/evm/go-x1/gossip/emitter/world.go +++ /dev/null @@ -1,92 +0,0 @@ -package emitter - -import ( - "errors" - "sync" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/valkeystore" - "github.com/Fantom-foundation/go-opera/vecmt" -) - -var ( - ErrNotEnoughGasPower = errors.New("not enough gas power") -) - -type ( - // External world - External interface { - sync.Locker - Reader - - Check(e *inter.EventPayload, parents inter.Events) error - Process(*inter.EventPayload) error - Broadcast(*inter.EventPayload) - Build(*inter.MutableEventPayload, func()) error - DagIndex() *vecmt.Index - - IsBusy() bool - IsSynced() bool - PeersNum() int - - StateDB() *state.StateDB - } - - // aliases for mock generator - Signer valkeystore.SignerI - TxSigner types.Signer - - // World is an emitter's environment - World struct { - External - TxPool TxPool - Signer valkeystore.SignerI - TxSigner types.Signer - } -) - -type LlrReader interface { - GetLowestBlockToDecide() idx.Block - GetLastBV(id idx.ValidatorID) *idx.Block - GetBlockRecordHash(idx.Block) *hash.Hash - GetBlockEpoch(idx.Block) idx.Epoch - - GetLowestEpochToDecide() idx.Epoch - GetLastEV(id idx.ValidatorID) *idx.Epoch - GetEpochRecordHash(epoch idx.Epoch) *hash.Hash -} - -// Reader is a callback for getting events from an external storage. -type Reader interface { - LlrReader - GetLatestBlockIndex() idx.Block - GetEpochValidators() (*pos.Validators, idx.Epoch) - GetHistoryEpochState(epoch idx.Epoch) *iblockproc.EpochState - GetEvent(hash.Event) *inter.Event - GetEventPayload(hash.Event) *inter.EventPayload - GetLastEvent(epoch idx.Epoch, from idx.ValidatorID) *hash.Event - GetHeads(idx.Epoch) hash.Events - GetGenesisTime() inter.Timestamp - GetRules() opera.Rules -} - -type TxPool interface { - // Has returns an indicator whether txpool has a transaction cached with the - // given hash. - Has(hash common.Hash) bool - // Pending should return pending transactions. - // The slice should be modifiable by the caller. - Pending(enforceTips bool) (map[common.Address]types.Transactions, error) - - // Count returns the total number of transactions - Count() int -} diff --git a/evm/go-x1/gossip/emitter_world.go b/evm/go-x1/gossip/emitter_world.go deleted file mode 100644 index 6b81f89..0000000 --- a/evm/go-x1/gossip/emitter_world.go +++ /dev/null @@ -1,111 +0,0 @@ -package gossip - -import ( - "sync/atomic" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/utils/wgmutex" - "github.com/Fantom-foundation/go-opera/valkeystore" - "github.com/Fantom-foundation/go-opera/vecmt" -) - -type emitterWorldProc struct { - s *Service -} - -type emitterWorldRead struct { - *Store -} - -// emitterWorld implements emitter.World interface -type emitterWorld struct { - emitterWorldProc - emitterWorldRead - *wgmutex.WgMutex - emitter.TxPool - valkeystore.SignerI - types.Signer -} - -func (ew *emitterWorldProc) Check(emitted *inter.EventPayload, parents inter.Events) error { - // sanity check - return ew.s.checkers.Validate(emitted, parents.Interfaces()) -} - -func (ew *emitterWorldProc) Process(emitted *inter.EventPayload) error { - done := ew.s.procLogger.EventConnectionStarted(emitted, true) - defer done() - return ew.s.processEvent(emitted) -} - -func (ew *emitterWorldProc) Broadcast(emitted *inter.EventPayload) { - // PM listens and will broadcast it - ew.s.feed.newEmittedEvent.Send(emitted) -} - -func (ew *emitterWorldProc) Build(e *inter.MutableEventPayload, onIndexed func()) error { - return ew.s.buildEvent(e, onIndexed) -} - -func (ew *emitterWorldProc) DagIndex() *vecmt.Index { - return ew.s.dagIndexer -} - -func (ew *emitterWorldProc) IsBusy() bool { - return atomic.LoadUint32(&ew.s.eventBusyFlag) != 0 || atomic.LoadUint32(&ew.s.blockBusyFlag) != 0 -} - -func (ew *emitterWorldProc) StateDB() *state.StateDB { - statedb, err := ew.s.store.evm.StateDB(ew.s.store.GetBlockState().FinalizedStateRoot) - if err != nil { - return nil - } - return statedb -} - -func (ew *emitterWorldProc) IsSynced() bool { - return ew.s.handler.syncStatus.AcceptEvents() -} - -func (ew *emitterWorldProc) PeersNum() int { - return ew.s.handler.peers.Len() -} - -func (ew *emitterWorldRead) GetHeads(epoch idx.Epoch) hash.Events { - return ew.Store.GetHeadsSlice(epoch) -} - -func (ew *emitterWorldRead) GetLastEvent(epoch idx.Epoch, from idx.ValidatorID) *hash.Event { - return ew.Store.GetLastEvent(epoch, from) -} - -func (ew *emitterWorldRead) GetLowestBlockToDecide() idx.Block { - return ew.Store.GetLlrState().LowestBlockToDecide -} - -func (ew *emitterWorldRead) GetBlockRecordHash(n idx.Block) *hash.Hash { - return ew.Store.GetBlockRecordHash(n) -} - -func (ew *emitterWorldRead) GetBlockEpoch(block idx.Block) idx.Epoch { - return ew.Store.FindBlockEpoch(block) -} - -func (ew *emitterWorldRead) GetLowestEpochToDecide() idx.Epoch { - return ew.Store.GetLlrState().LowestEpochToDecide -} - -func (ew *emitterWorldRead) GetEpochRecordHash(epoch idx.Epoch) *hash.Hash { - record := ew.Store.GetFullEpochRecord(epoch) - if record == nil { - return nil - } - h := record.Hash() - return &h -} diff --git a/evm/go-x1/gossip/enr_entry.go b/evm/go-x1/gossip/enr_entry.go deleted file mode 100644 index f6ba4e4..0000000 --- a/evm/go-x1/gossip/enr_entry.go +++ /dev/null @@ -1,23 +0,0 @@ -package gossip - -import ( - "github.com/ethereum/go-ethereum/core/forkid" - "github.com/ethereum/go-ethereum/rlp" -) - -// Enr is ENR entry which advertises eth protocol -// on the discovery network. -type Enr struct { - ForkID forkid.ID - // Ignore additional fields (for forward compatibility). - Rest []rlp.RawValue `rlp:"tail"` -} - -// ENRKey implements enr.Entry. -func (e Enr) ENRKey() string { - return "opera" -} - -func (s *Service) currentEnr() *Enr { - return &Enr{} -} diff --git a/evm/go-x1/gossip/eth_state_adapter.go b/evm/go-x1/gossip/eth_state_adapter.go deleted file mode 100644 index a8a3c7b..0000000 --- a/evm/go-x1/gossip/eth_state_adapter.go +++ /dev/null @@ -1,36 +0,0 @@ -package gossip - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/state/snapshot" -) - -// ethBlockChain wraps store to implement eth/protocols/snap.BlockChain interface. -type ethBlockChain struct { - store *Store -} - -func newEthBlockChain(s *Store) (*ethBlockChain, error) { - bc := ðBlockChain{ - store: s, - } - - return bc, nil -} - -// StateCache returns the caching database underpinning the blockchain instance. -func (bc *ethBlockChain) StateCache() state.Database { - return bc.store.LastKvdbEvmSnapshot().EvmState -} - -// ContractCode retrieves a blob of data associated with a contract hash -// either from ephemeral in-memory cache, or from persistent storage. -func (bc *ethBlockChain) ContractCode(hash common.Hash) ([]byte, error) { - return bc.store.LastKvdbEvmSnapshot().EvmState.ContractCode(common.Hash{}, hash) -} - -// Snapshots returns the blockchain snapshot tree to paused it during sync. -func (bc *ethBlockChain) Snapshots() *snapshot.Tree { - return bc.store.LastKvdbEvmSnapshot().Snapshots() -} diff --git a/evm/go-x1/gossip/ethapi_backend.go b/evm/go-x1/gossip/ethapi_backend.go deleted file mode 100644 index 1156454..0000000 --- a/evm/go-x1/gossip/ethapi_backend.go +++ /dev/null @@ -1,543 +0,0 @@ -package gossip - -import ( - "context" - "fmt" - "math/big" - "strconv" - "strings" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/ethdb" - notify "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rpc" - "github.com/pkg/errors" - - "github.com/Fantom-foundation/go-opera/ethapi" - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/topicsdb" - "github.com/Fantom-foundation/go-opera/tracing" -) - -// EthAPIBackend implements ethapi.Backend. -type EthAPIBackend struct { - extRPCEnabled bool - svc *Service - state *EvmStateReader - signer types.Signer - allowUnprotectedTxs bool -} - -// SetExtRPCEnabled updates extRPCEnabled -func (b *EthAPIBackend) SetExtRPCEnabled(v bool) { - b.extRPCEnabled = v -} - -// ChainConfig returns the active chain configuration. -func (b *EthAPIBackend) ChainConfig() *params.ChainConfig { - return b.svc.store.GetEvmChainConfig() -} - -func (b *EthAPIBackend) CurrentBlock() *evmcore.EvmBlock { - return b.state.CurrentBlock() -} - -func (b *EthAPIBackend) ResolveRpcBlockNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (idx.Block, error) { - latest := b.svc.store.GetLatestBlockIndex() - if number, ok := blockNrOrHash.Number(); ok && (number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber) { - return latest, nil - } else if number, ok := blockNrOrHash.Number(); ok { - if idx.Block(number) > latest { - return 0, errors.New("block not found") - } - return idx.Block(number), nil - } else if h, ok := blockNrOrHash.Hash(); ok { - index := b.svc.store.GetBlockIndex(hash.Event(h)) - if index == nil { - return 0, errors.New("block not found") - } - return *index, nil - } - return 0, errors.New("unknown header selector") -} - -// HeaderByNumber returns evm block header by its number, or nil if not exists. -func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*evmcore.EvmHeader, error) { - blk, err := b.BlockByNumber(ctx, number) - if err != nil { - return nil, err - } - if blk == nil { - return nil, nil - } - return blk.Header(), err -} - -// HeaderByHash returns evm block header by its (atropos) hash, or nil if not exists. -func (b *EthAPIBackend) HeaderByHash(ctx context.Context, h common.Hash) (*evmcore.EvmHeader, error) { - index := b.svc.store.GetBlockIndex(hash.Event(h)) - if index == nil { - return nil, nil - } - return b.HeaderByNumber(ctx, rpc.BlockNumber(*index)) -} - -// BlockByNumber returns evm block by its number, or nil if not exists. -func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*evmcore.EvmBlock, error) { - if number == rpc.PendingBlockNumber { - number = rpc.LatestBlockNumber - } - // Otherwise, resolve and return the block - var blk *evmcore.EvmBlock - if number == rpc.LatestBlockNumber { - blk = b.state.CurrentBlock() - } else { - n := uint64(number.Int64()) - blk = b.state.GetBlock(common.Hash{}, n) - } - - return blk, nil -} - -// StateAndHeaderByNumberOrHash returns evm state and block header by block number or block hash, err if not exists. -func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *evmcore.EvmHeader, error) { - var header *evmcore.EvmHeader - if number, ok := blockNrOrHash.Number(); ok && (number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber) { - header = &b.state.CurrentBlock().EvmHeader - } else if number, ok := blockNrOrHash.Number(); ok { - header = b.state.GetHeader(common.Hash{}, uint64(number)) - } else if h, ok := blockNrOrHash.Hash(); ok { - index := b.svc.store.GetBlockIndex(hash.Event(h)) - if index == nil { - return nil, nil, errors.New("header not found") - } - header = b.state.GetHeader(common.Hash{}, uint64(*index)) - } else { - return nil, nil, errors.New("unknown header selector") - } - if header == nil { - return nil, nil, errors.New("header not found") - } - stateDb, err := b.svc.store.evm.StateDB(hash.Hash(header.Root)) - if err != nil { - return nil, nil, err - } - return stateDb, header, nil -} - -// decodeShortEventID decodes ShortID -// example of a ShortID: "5:26:a2395846", where 5 is epoch, 26 is lamport, a2395846 are first bytes of the hash -// s is a string splitted by ":" separator -func decodeShortEventID(s []string) (idx.Epoch, idx.Lamport, []byte, error) { - if len(s) != 3 { - return 0, 0, nil, errors.New("incorrect format of short event ID (need Epoch:Lamport:Hash") - } - epoch, err := strconv.ParseUint(s[0], 10, 32) - if err != nil { - return 0, 0, nil, errors.Wrap(err, "short hash parsing error (lamport)") - } - lamport, err := strconv.ParseUint(s[1], 10, 32) - if err != nil { - return 0, 0, nil, errors.Wrap(err, "short hash parsing error (lamport)") - } - return idx.Epoch(epoch), idx.Lamport(lamport), common.FromHex(s[2]), nil -} - -// GetFullEventID "converts" ShortID to full event's hash, by searching in events DB. -func (b *EthAPIBackend) GetFullEventID(shortEventID string) (hash.Event, error) { - s := strings.Split(shortEventID, ":") - if len(s) == 1 { - // it's a full hash - return hash.HexToEventHash(shortEventID), nil - } - // short hash - epoch, lamport, prefix, err := decodeShortEventID(s) - if err != nil { - return hash.Event{}, err - } - - options := b.svc.store.FindEventHashes(epoch, lamport, prefix) - if len(options) == 0 { - return hash.Event{}, errors.New("event not found by short ID") - } - if len(options) > 1 { - return hash.Event{}, errors.New("there're multiple events with the same short ID, please use full ID") - } - return options[0], nil -} - -// GetEventPayload returns Lachesis event by hash or short ID. -func (b *EthAPIBackend) GetEventPayload(ctx context.Context, shortEventID string) (*inter.EventPayload, error) { - id, err := b.GetFullEventID(shortEventID) - if err != nil { - return nil, err - } - return b.svc.store.GetEventPayload(id), nil -} - -// GetEvent returns the Lachesis event header by hash or short ID. -func (b *EthAPIBackend) GetEvent(ctx context.Context, shortEventID string) (*inter.Event, error) { - id, err := b.GetFullEventID(shortEventID) - if err != nil { - return nil, err - } - return b.svc.store.GetEvent(id), nil -} - -// GetHeads returns IDs of all the epoch events with no descendants. -// * When epoch is -2 the heads for latest epoch are returned. -// * When epoch is -1 the heads for latest sealed epoch are returned. -func (b *EthAPIBackend) GetHeads(ctx context.Context, epoch rpc.BlockNumber) (heads hash.Events, err error) { - current := b.svc.store.GetEpoch() - - requested, err := b.epochWithDefault(ctx, epoch) - if err != nil { - return nil, err - } - - if requested == current { - heads = b.svc.store.GetHeadsSlice(requested) - } else { - err = errors.New("heads for previous epochs are not available") - return - } - - if heads == nil { - heads = hash.Events{} - } - - return -} - -func (b *EthAPIBackend) epochWithDefault(ctx context.Context, epoch rpc.BlockNumber) (requested idx.Epoch, err error) { - current := b.svc.store.GetEpoch() - - switch { - case epoch == rpc.PendingBlockNumber: - requested = current - case epoch == rpc.LatestBlockNumber: - requested = current - 1 - case epoch >= 0 && idx.Epoch(epoch) <= current: - requested = idx.Epoch(epoch) - default: - err = errors.New("epoch is not in range") - return - } - return requested, nil -} - -// ForEachEpochEvent iterates all the events which are observed by head, and accepted by a filter. -// filter CANNOT called twice for the same event. -func (b *EthAPIBackend) ForEachEpochEvent(ctx context.Context, epoch rpc.BlockNumber, onEvent func(event *inter.EventPayload) bool) error { - requested, err := b.epochWithDefault(ctx, epoch) - if err != nil { - return err - } - - b.svc.store.ForEachEpochEvent(requested, onEvent) - return nil -} - -func (b *EthAPIBackend) BlockByHash(ctx context.Context, h common.Hash) (*evmcore.EvmBlock, error) { - index := b.svc.store.GetBlockIndex(hash.Event(h)) - if index == nil { - return nil, nil - } - - if rpc.BlockNumber(*index) == rpc.PendingBlockNumber { - return nil, errors.New("pending block request isn't allowed") - } - // Otherwise resolve and return the block - var blk *evmcore.EvmBlock - if rpc.BlockNumber(*index) == rpc.LatestBlockNumber { - blk = b.state.CurrentBlock() - } else { - n := uint64(*index) - blk = b.state.GetBlock(common.Hash{}, n) - } - - return blk, nil -} - -// GetReceiptsByNumber returns receipts by block number. -func (b *EthAPIBackend) GetReceiptsByNumber(ctx context.Context, number rpc.BlockNumber) (types.Receipts, error) { - if !b.svc.config.TxIndex { - return nil, errors.New("transactions index is disabled (enable TxIndex and re-process the DAGs)") - } - - if number == rpc.PendingBlockNumber { - number = rpc.LatestBlockNumber - } - if number == rpc.LatestBlockNumber { - header := b.state.CurrentHeader() - number = rpc.BlockNumber(header.Number.Uint64()) - } - - block := b.state.GetBlock(common.Hash{}, uint64(number)) - receipts := b.svc.store.evm.GetReceipts(idx.Block(number), b.signer, block.Hash, block.Transactions) - return receipts, nil -} - -// GetReceipts retrieves the receipts for all transactions in a given block. -func (b *EthAPIBackend) GetReceipts(ctx context.Context, block common.Hash) (types.Receipts, error) { - number := b.svc.store.GetBlockIndex(hash.Event(block)) - if number == nil { - return nil, nil - } - - return b.GetReceiptsByNumber(ctx, rpc.BlockNumber(*number)) -} - -func (b *EthAPIBackend) GetLogs(ctx context.Context, block common.Hash) ([][]*types.Log, error) { - receipts, err := b.GetReceipts(ctx, block) - if receipts == nil || err != nil { - return nil, err - } - logs := make([][]*types.Log, receipts.Len()) - for i, receipt := range receipts { - logs[i] = receipt.Logs - } - return logs, nil -} - -func (b *EthAPIBackend) GetTd(_ common.Hash) *big.Int { - return big.NewInt(0) -} - -func (b *EthAPIBackend) GetEVM(ctx context.Context, msg evmcore.Message, state *state.StateDB, header *evmcore.EvmHeader, vmConfig *vm.Config) (*vm.EVM, func() error, error) { - vmError := func() error { return nil } - - if vmConfig == nil { - vmConfig = &opera.DefaultVMConfig - } - txContext := evmcore.NewEVMTxContext(msg) - context := evmcore.NewEVMBlockContext(header, b.state, nil) - config := b.ChainConfig() - return vm.NewEVM(context, txContext, state, config, *vmConfig), vmError, nil -} - -func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { - err := b.svc.txpool.AddLocal(signedTx) - if err == nil { - // NOTE: only sent txs tracing, see TxPool.addTxs() for all - tracing.StartTx(signedTx.Hash(), "EthAPIBackend.SendTx()") - } - return err -} - -func (b *EthAPIBackend) SubscribeLogsNotify(ch chan<- []*types.Log) notify.Subscription { - return b.svc.feed.SubscribeNewLogs(ch) -} - -func (b *EthAPIBackend) SubscribeNewBlockNotify(ch chan<- evmcore.ChainHeadNotify) notify.Subscription { - return b.svc.feed.SubscribeNewBlock(ch) -} - -func (b *EthAPIBackend) SubscribeNewTxsNotify(ch chan<- evmcore.NewTxsNotify) notify.Subscription { - return b.svc.txpool.SubscribeNewTxsNotify(ch) -} - -func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) { - pending, err := b.svc.txpool.Pending(false) - if err != nil { - return nil, err - } - var txs types.Transactions - for _, batch := range pending { - txs = append(txs, batch...) - } - return txs, nil -} - -func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction { - return b.svc.txpool.Get(hash) -} - -func (b *EthAPIBackend) GetTxPosition(txHash common.Hash) *evmstore.TxPosition { - return b.svc.store.evm.GetTxPosition(txHash) -} - -func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, uint64, uint64, error) { - if !b.svc.config.TxIndex { - return nil, 0, 0, errors.New("transactions index is disabled (enable TxIndex and re-process the DAG)") - } - - position := b.svc.store.evm.GetTxPosition(txHash) - if position == nil { - return nil, 0, 0, nil - } - - var tx *types.Transaction - if position.Event.IsZero() { - tx = b.svc.store.evm.GetTx(txHash) - } else { - event := b.svc.store.GetEventPayload(position.Event) - if position.EventOffset > uint32(event.Txs().Len()) { - return nil, 0, 0, fmt.Errorf("transactions index is corrupted (offset is larger than number of txs in event), event=%s, txid=%s, block=%d, offset=%d, txs_num=%d", - position.Event.String(), - txHash.String(), - position.Block, - position.EventOffset, - event.Txs().Len()) - } - tx = event.Txs()[position.EventOffset] - } - - return tx, uint64(position.Block), uint64(position.BlockOffset), nil -} - -func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { - return b.svc.txpool.Nonce(addr), nil -} - -func (b *EthAPIBackend) Stats() (pending int, queued int) { - return b.svc.txpool.Stats() -} - -func (b *EthAPIBackend) TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { - return b.svc.txpool.Content() -} - -// Progress returns current synchronization status of this node -func (b *EthAPIBackend) Progress() ethapi.PeerProgress { - p2pProgress := b.svc.handler.myProgress() - highestP2pProgress := b.svc.handler.highestPeerProgress() - lastBlock := b.svc.store.GetBlock(p2pProgress.LastBlockIdx) - - return ethapi.PeerProgress{ - CurrentEpoch: p2pProgress.Epoch, - CurrentBlock: p2pProgress.LastBlockIdx, - CurrentBlockHash: p2pProgress.LastBlockAtropos, - CurrentBlockTime: lastBlock.Time, - HighestBlock: highestP2pProgress.LastBlockIdx, - HighestEpoch: highestP2pProgress.Epoch, - } -} - -func (b *EthAPIBackend) TxPoolContentFrom(addr common.Address) (types.Transactions, types.Transactions) { - return b.svc.txpool.ContentFrom(addr) -} - -func (b *EthAPIBackend) SuggestGasTipCap(ctx context.Context, certainty uint64) *big.Int { - return b.svc.gpo.SuggestTip(certainty) -} - -func (b *EthAPIBackend) EffectiveMinGasPrice(ctx context.Context) *big.Int { - return b.svc.gpo.EffectiveMinGasPrice() -} - -func (b *EthAPIBackend) ChainDb() ethdb.Database { - return b.svc.store.evm.EvmDb -} - -func (b *EthAPIBackend) AccountManager() *accounts.Manager { - return b.svc.AccountManager() -} - -func (b *EthAPIBackend) ExtRPCEnabled() bool { - return b.extRPCEnabled -} - -func (b *EthAPIBackend) UnprotectedAllowed() bool { - return b.allowUnprotectedTxs -} - -func (b *EthAPIBackend) RPCGasCap() uint64 { - return b.svc.config.RPCGasCap -} - -func (b *EthAPIBackend) RPCEVMTimeout() time.Duration { - return b.svc.config.RPCEVMTimeout -} - -func (b *EthAPIBackend) RPCTxFeeCap() float64 { - return b.svc.config.RPCTxFeeCap -} - -func (b *EthAPIBackend) EvmLogIndex() topicsdb.Index { - return b.svc.store.evm.EvmLogs -} - -// CurrentEpoch returns current epoch number. -func (b *EthAPIBackend) CurrentEpoch(ctx context.Context) idx.Epoch { - return b.svc.store.GetEpoch() -} - -func (b *EthAPIBackend) MinGasPrice() *big.Int { - return b.state.MinGasPrice() -} -func (b *EthAPIBackend) MaxGasLimit() uint64 { - return b.state.MaxGasLimit() -} - -func (b *EthAPIBackend) GetUptime(ctx context.Context, vid idx.ValidatorID) (*big.Int, error) { - // Note: loads bs and es atomically to avoid a race condition - bs, es := b.svc.store.GetBlockEpochState() - if !es.Validators.Exists(vid) { - return nil, nil - } - return new(big.Int).SetUint64(uint64(bs.GetValidatorState(vid, es.Validators).Uptime)), nil -} - -func (b *EthAPIBackend) GetOriginatedFee(ctx context.Context, vid idx.ValidatorID) (*big.Int, error) { - // Note: loads bs and es atomically to avoid a race condition - bs, es := b.svc.store.GetBlockEpochState() - if !es.Validators.Exists(vid) { - return nil, nil - } - return bs.GetValidatorState(vid, es.Validators).Originated, nil -} - -func (b *EthAPIBackend) GetDowntime(ctx context.Context, vid idx.ValidatorID) (idx.Block, inter.Timestamp, error) { - // Note: loads bs and es atomically to avoid a race condition - bs, es := b.svc.store.GetBlockEpochState() - if !es.Validators.Exists(vid) { - return 0, 0, nil - } - vs := bs.GetValidatorState(vid, es.Validators) - missedBlocks := idx.Block(0) - if bs.LastBlock.Idx > vs.LastBlock { - missedBlocks = bs.LastBlock.Idx - vs.LastBlock - } - missedTime := inter.Timestamp(0) - if bs.LastBlock.Time > vs.LastOnlineTime { - missedTime = bs.LastBlock.Time - vs.LastOnlineTime - } - if missedBlocks < es.Rules.Economy.BlockMissedSlack { - return 0, 0, nil - } - return missedBlocks, missedTime, nil -} - -func (b *EthAPIBackend) GetEpochBlockState(ctx context.Context, epoch rpc.BlockNumber) (*iblockproc.BlockState, *iblockproc.EpochState, error) { - if epoch == rpc.PendingBlockNumber { - bs, es := b.svc.store.GetBlockState(), b.svc.store.GetEpochState() - return &bs, &es, nil - } - if epoch == rpc.LatestBlockNumber { - epoch = rpc.BlockNumber(b.svc.store.GetEpoch()) - } - bs, es := b.svc.store.GetHistoryBlockEpochState(idx.Epoch(epoch)) - return bs, es, nil -} - -func (b *EthAPIBackend) CalcBlockExtApi() bool { - return b.svc.config.RPCBlockExt -} - -func (b *EthAPIBackend) SealedEpochTiming(ctx context.Context) (start inter.Timestamp, end inter.Timestamp) { - es := b.svc.store.GetEpochState() - return es.PrevEpochStart, es.EpochStart -} diff --git a/evm/go-x1/gossip/evm_state_reader.go b/evm/go-x1/gossip/evm_state_reader.go deleted file mode 100644 index d8a2464..0000000 --- a/evm/go-x1/gossip/evm_state_reader.go +++ /dev/null @@ -1,143 +0,0 @@ -package gossip - -import ( - "math/big" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/gasprice" - "github.com/Fantom-foundation/go-opera/opera" -) - -type EvmStateReader struct { - *ServiceFeed - - store *Store - gpo *gasprice.Oracle -} - -func NewEvmStateReader(s *Store) *EvmStateReader { - return &EvmStateReader{ - store: s, - } -} - -func (s *Service) GetEvmStateReader() *EvmStateReader { - return &EvmStateReader{ - ServiceFeed: &s.feed, - store: s.store, - gpo: s.gpo, - } -} - -// MinGasPrice returns current hard lower bound for gas price -func (r *EvmStateReader) MinGasPrice() *big.Int { - return r.store.GetRules().Economy.MinGasPrice -} - -// EffectiveMinTip returns current soft lower bound for gas tip -func (r *EvmStateReader) EffectiveMinTip() *big.Int { - min := r.MinGasPrice() - est := r.gpo.EffectiveMinGasPrice() - est.Sub(est, min) - if est.Sign() < 0 { - return new(big.Int) - } - return est -} - -func (r *EvmStateReader) MaxGasLimit() uint64 { - rules := r.store.GetRules() - maxEmptyEventGas := rules.Economy.Gas.EventGas + - uint64(rules.Dag.MaxParents-rules.Dag.MaxFreeParents)*rules.Economy.Gas.ParentGas + - uint64(rules.Dag.MaxExtraData)*rules.Economy.Gas.ExtraDataGas - if rules.Economy.Gas.MaxEventGas < maxEmptyEventGas { - return 0 - } - return rules.Economy.Gas.MaxEventGas - maxEmptyEventGas -} - -func (r *EvmStateReader) Config() *params.ChainConfig { - return r.store.GetEvmChainConfig() -} - -func (r *EvmStateReader) CurrentBlock() *evmcore.EvmBlock { - n := r.store.GetLatestBlockIndex() - - return r.getBlock(hash.Event{}, n, true) -} - -func (r *EvmStateReader) CurrentHeader() *evmcore.EvmHeader { - n := r.store.GetLatestBlockIndex() - - return r.getBlock(hash.Event{}, n, false).Header() -} - -func (r *EvmStateReader) GetHeader(h common.Hash, n uint64) *evmcore.EvmHeader { - return r.getBlock(hash.Event(h), idx.Block(n), false).Header() -} - -func (r *EvmStateReader) GetBlock(h common.Hash, n uint64) *evmcore.EvmBlock { - return r.getBlock(hash.Event(h), idx.Block(n), true) -} - -func (r *EvmStateReader) getBlock(h hash.Event, n idx.Block, readTxs bool) *evmcore.EvmBlock { - block := r.store.GetBlock(n) - if block == nil { - return nil - } - if (h != hash.Event{}) && (h != block.Atropos) { - return nil - } - if readTxs { - if cached := r.store.EvmStore().GetCachedEvmBlock(n); cached != nil { - return cached - } - } - - var transactions types.Transactions - if readTxs { - transactions = r.store.GetBlockTxs(n, block) - } else { - transactions = make(types.Transactions, 0) - } - - // find block rules - epoch := block.Atropos.Epoch() - es := r.store.GetHistoryEpochState(epoch) - var rules opera.Rules - if es != nil { - rules = es.Rules - } - var prev hash.Event - if n != 0 { - block := r.store.GetBlock(n - 1) - if block != nil { - prev = block.Atropos - } - } - evmHeader := evmcore.ToEvmHeader(block, n, prev, rules) - - var evmBlock *evmcore.EvmBlock - if readTxs { - evmBlock = evmcore.NewEvmBlock(evmHeader, transactions) - r.store.EvmStore().SetCachedEvmBlock(n, evmBlock) - } else { - // not completed block here - evmBlock = &evmcore.EvmBlock{ - EvmHeader: *evmHeader, - } - } - - return evmBlock -} - -func (r *EvmStateReader) StateAt(root common.Hash) (*state.StateDB, error) { - return r.store.evm.StateDB(hash.Hash(root)) -} diff --git a/evm/go-x1/gossip/evm_test.go b/evm/go-x1/gossip/evm_test.go deleted file mode 100644 index b56075d..0000000 --- a/evm/go-x1/gossip/evm_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package gossip - -// Simple ballot contract -//go:generate bash -c "docker run --rm -v $(pwd)/contract/ballot:/src -v $(pwd)/contract:/dst ethereum/solc:0.5.12 -o /dst/solc/ --optimize --optimize-runs=2000 --bin --abi --allow-paths /src --overwrite /src/Ballot.sol" -//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen --bin=contract/solc/Ballot.bin --abi=contract/solc/Ballot.abi --pkg=ballot --type=Contract --out=contract/ballot/contract.go - -import ( - "math/big" - "testing" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/gossip/contract/ballot" - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/utils" -) - -func BenchmarkBallotTxsProcessing(b *testing.B) { - logger.SetLevel("warn") - logger.SetTestMode(b) - require := require.New(b) - - env := newTestEnv(2, 3) - defer env.Close() - - for bi := 0; bi < b.N; bi++ { - count := idx.ValidatorID(10) - - proposals := [][32]byte{ - ballotOption("Option 1"), - ballotOption("Option 2"), - ballotOption("Option 3"), - } - - // contract deploy - addr, tx, cBallot, err := ballot.DeployBallot(env.Pay(1), env, proposals) - require.NoError(err) - require.NotNil(cBallot) - r, err := env.ApplyTxs(nextEpoch, tx) - require.NoError(err) - - require.Equal(addr, r[0].ContractAddress) - - admin, err := cBallot.Chairperson(env.ReadOnly()) - require.NoError(err) - require.Equal(env.Address(1), admin) - - txs := make([]*types.Transaction, 0, count-1) - flushTxs := func() { - if len(txs) != 0 { - env.ApplyTxs(nextEpoch, txs...) - } - txs = txs[:0] - } - - // Init accounts - for vid := idx.ValidatorID(2); vid <= count; vid++ { - tx := env.Transfer(1, vid, utils.ToFtm(10)) - txs = append(txs, tx) - if len(txs) > 2 { - flushTxs() - } - } - flushTxs() - - // GiveRightToVote - for vid := idx.ValidatorID(1); vid <= count; vid++ { - tx, err := cBallot.GiveRightToVote(env.Pay(1), env.Address(vid)) - require.NoError(err) - txs = append(txs, tx) - if len(txs) > 2 { - flushTxs() - } - } - flushTxs() - - // Vote - for vid := idx.ValidatorID(1); vid <= count; vid++ { - proposal := big.NewInt(int64(vid) % int64(len(proposals))) - tx, err := cBallot.Vote(env.Pay(vid), proposal) - require.NoError(err) - txs = append(txs, tx) - if len(txs) > 2 { - flushTxs() - } - } - flushTxs() - - // Winner - _, err = cBallot.WinnerName(env.ReadOnly()) - require.NoError(err) - } -} - -func ballotOption(str string) (res [32]byte) { - buf := []byte(str) - if len(buf) > 32 { - panic("string too long") - } - copy(res[:], buf) - return -} diff --git a/evm/go-x1/gossip/evmstore/apply_genesis.go b/evm/go-x1/gossip/evmstore/apply_genesis.go deleted file mode 100644 index 1e9fb3b..0000000 --- a/evm/go-x1/gossip/evmstore/apply_genesis.go +++ /dev/null @@ -1,48 +0,0 @@ -package evmstore - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb/batched" - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/utils/adapters/ethdb2kvdb" - "github.com/Fantom-foundation/go-opera/utils/dbutil/autocompact" -) - -// ApplyGenesis writes initial state. -func (s *Store) ApplyGenesis(g genesis.Genesis) (err error) { - db := batched.Wrap(autocompact.Wrap2M(ethdb2kvdb.Wrap(s.EvmDb), opt.GiB, 16*opt.GiB, true, "evm")) - g.RawEvmItems.ForEach(func(key, value []byte) bool { - err = db.Put(key, value) - if err != nil { - return false - } - return true - }) - if err != nil { - return err - } - return db.Write() -} - -func (s *Store) WrapTablesAsBatched() (unwrap func()) { - origTables := s.table - - batchedTxs := batched.Wrap(s.table.Txs) - s.table.Txs = batchedTxs - - batchedTxPositions := batched.Wrap(s.table.TxPositions) - s.table.TxPositions = batchedTxPositions - - unwrapLogs := s.EvmLogs.WrapTablesAsBatched() - - batchedReceipts := batched.Wrap(autocompact.Wrap2M(s.table.Receipts, opt.GiB, 16*opt.GiB, false, "receipts")) - s.table.Receipts = batchedReceipts - return func() { - _ = batchedTxs.Flush() - _ = batchedTxPositions.Flush() - _ = batchedReceipts.Flush() - unwrapLogs() - s.table = origTables - } -} diff --git a/evm/go-x1/gossip/evmstore/config.go b/evm/go-x1/gossip/evmstore/config.go deleted file mode 100644 index c94095a..0000000 --- a/evm/go-x1/gossip/evmstore/config.go +++ /dev/null @@ -1,64 +0,0 @@ -package evmstore - -import ( - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" - "github.com/syndtr/goleveldb/leveldb/opt" -) - -type ( - // StoreCacheConfig is a config for the db. - StoreCacheConfig struct { - // Cache size for Receipts (size in bytes). - ReceiptsSize uint - // Cache size for Receipts (number of blocks). - ReceiptsBlocks int - // Cache size for TxPositions. - TxPositions int - // Cache size for EVM database. - EvmDatabase int - // Cache size for EVM snapshot. - EvmSnap int - // Cache size for EvmBlock (number of blocks). - EvmBlocksNum int - // Cache size for EvmBlock (size in bytes). - EvmBlocksSize uint - // Disk journal for saving clean cache entries. - TrieCleanJournal string - // Whether to disable trie write caching and GC altogether (archive node) - TrieDirtyDisabled bool - // Memory limit (MB) at which to start flushing dirty trie nodes to disk - TrieDirtyLimit uint - // Whether to enable greedy gc mode - GreedyGC bool - } - // StoreConfig is a config for store db. - StoreConfig struct { - Cache StoreCacheConfig - // Enables tracking of SHA3 preimages in the VM - EnablePreimageRecording bool - } -) - -// DefaultStoreConfig for product. -func DefaultStoreConfig(scale cachescale.Func) StoreConfig { - return StoreConfig{ - Cache: StoreCacheConfig{ - ReceiptsSize: scale.U(4 * opt.MiB), - ReceiptsBlocks: scale.I(4000), - TxPositions: scale.I(20000), - EvmDatabase: scale.I(32 * opt.MiB), - EvmSnap: scale.I(32 * opt.MiB), - EvmBlocksNum: scale.I(5000), - EvmBlocksSize: scale.U(6 * opt.MiB), - TrieDirtyDisabled: true, - GreedyGC: false, - TrieDirtyLimit: scale.U(256 * opt.MiB), - }, - EnablePreimageRecording: true, - } -} - -// LiteStoreConfig is for tests or inmemory. -func LiteStoreConfig() StoreConfig { - return DefaultStoreConfig(cachescale.Ratio{Base: 10, Target: 1}) -} diff --git a/evm/go-x1/gossip/evmstore/evmpruner/bloom.go b/evm/go-x1/gossip/evmstore/evmpruner/bloom.go deleted file mode 100644 index e7d7ed8..0000000 --- a/evm/go-x1/gossip/evmstore/evmpruner/bloom.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmpruner - -import ( - "encoding/binary" - "errors" - "os" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/log" - bloomfilter "github.com/holiman/bloomfilter/v2" -) - -// stateBloomHasher is a wrapper around a byte blob to satisfy the interface API -// requirements of the bloom library used. It's used to convert a trie hash or -// contract code hash into a 64 bit mini hash. -type stateBloomHasher []byte - -func (f stateBloomHasher) Write(p []byte) (n int, err error) { panic("not implemented") } -func (f stateBloomHasher) Sum(b []byte) []byte { panic("not implemented") } -func (f stateBloomHasher) Reset() { panic("not implemented") } -func (f stateBloomHasher) BlockSize() int { panic("not implemented") } -func (f stateBloomHasher) Size() int { return 8 } -func (f stateBloomHasher) Sum64() uint64 { return binary.BigEndian.Uint64(f) } - -// stateBloom is a bloom filter used during the state convesion(snapshot->state). -// The keys of all generated entries will be recorded here so that in the pruning -// stage the entries belong to the specific version can be avoided for deletion. -// -// The false-positive is allowed here. The "false-positive" entries means they -// actually don't belong to the specific version but they are not deleted in the -// pruning. The downside of the false-positive allowance is we may leave some "dangling" -// nodes in the disk. But in practice the it's very unlike the dangling node is -// state root. So in theory this pruned state shouldn't be visited anymore. Another -// potential issue is for fast sync. If we do another fast sync upon the pruned -// database, it's problematic which will stop the expansion during the syncing. -// TODO address it @rjl493456442 @holiman @karalabe. -// -// After the entire state is generated, the bloom filter should be persisted into -// the disk. It indicates the whole generation procedure is finished. -type stateBloom struct { - bloom *bloomfilter.Filter -} - -// newStateBloomWithSize creates a brand new state bloom for state generation. -// The bloom filter will be created by the passing bloom filter size. According -// to the https://hur.st/bloomfilter/?n=600000000&p=&m=2048MB&k=4, the parameters -// are picked so that the false-positive rate for mainnet is low enough. -func newStateBloomWithSize(size uint64) (*stateBloom, error) { - bloom, err := bloomfilter.New(size*1024*1024*8, 4) - if err != nil { - return nil, err - } - return &stateBloom{bloom: bloom}, nil -} - -// NewStateBloomFromDisk loads the state bloom from the given file. -// In this case the assumption is held the bloom filter is complete. -func NewStateBloomFromDisk(filename string) (*stateBloom, error) { - bloom, _, err := bloomfilter.ReadFile(filename) - if err != nil { - return nil, err - } - return &stateBloom{bloom: bloom}, nil -} - -// Commit flushes the bloom filter content into the disk and marks the bloom -// as complete. -func (bloom *stateBloom) Commit(filename, tempname string) error { - log.Info("Writing state bloom to disk", "name", filename) - // Write the bloom out into a temporary file - _, err := bloom.bloom.WriteFile(tempname) - if err != nil { - return err - } - // Ensure the file is synced to disk - f, err := os.Open(tempname) - if err != nil { - return err - } - if err := f.Sync(); err != nil { - f.Close() - return err - } - f.Close() - - log.Info("State bloom filter committed", "name", filename) - // Move the teporary file into it's final location - return os.Rename(tempname, filename) -} - -// Put implements the KeyValueWriter interface. But here only the key is needed. -func (bloom *stateBloom) Put(key []byte, value []byte) error { - // If the key length is not 32bytes, ensure it's contract code - // entry with new scheme. - if len(key) != common.HashLength { - isCode, codeKey := rawdb.IsCodeKey(key) - if !isCode { - return errors.New("invalid entry") - } - bloom.bloom.Add(stateBloomHasher(codeKey)) - return nil - } - bloom.bloom.Add(stateBloomHasher(key)) - return nil -} - -// Delete removes the key from the key-value data store. -func (bloom *stateBloom) Delete(key []byte) error { panic("not supported") } - -// Contain is the wrapper of the underlying contains function which -// reports whether the key is contained. -// - If it says yes, the key may be contained -// - If it says no, the key is definitely not contained. -func (bloom *stateBloom) Contain(key []byte) (bool, error) { - return bloom.bloom.Contains(stateBloomHasher(key)), nil -} diff --git a/evm/go-x1/gossip/evmstore/evmpruner/exact.go b/evm/go-x1/gossip/evmstore/evmpruner/exact.go deleted file mode 100644 index beb4213..0000000 --- a/evm/go-x1/gossip/evmstore/evmpruner/exact.go +++ /dev/null @@ -1,48 +0,0 @@ -package evmpruner - -import ( - "errors" - "io" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/leveldb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/syndtr/goleveldb/leveldb/opt" -) - -type exactSetStore struct { - db kvdb.Store -} - -func NewLevelDBSet(name string) (*exactSetStore, io.Closer, error) { - db, err := leveldb.New(name, 256*opt.MiB, 0, nil, nil) - if err != nil { - return nil, nil, err - } - return &exactSetStore{db}, db, nil -} - -func (set *exactSetStore) Put(key []byte, _ []byte) error { - // If the key length is not 32bytes, ensure it's contract code - // entry with new scheme. - if len(key) != common.HashLength { - isCode, codeKey := rawdb.IsCodeKey(key) - if !isCode { - return errors.New("invalid entry") - } - return set.db.Put(codeKey, []byte{}) - } - return set.db.Put(key, []byte{}) -} - -func (set *exactSetStore) Delete(key []byte) error { panic("not supported") } - -func (set *exactSetStore) Contain(key []byte) (bool, error) { - return set.db.Has(key) -} - -func (set *exactSetStore) Commit(filename, tempname string) error { - // No need in manual writing - return nil -} diff --git a/evm/go-x1/gossip/evmstore/evmpruner/pruner.go b/evm/go-x1/gossip/evmstore/evmpruner/pruner.go deleted file mode 100644 index b645031..0000000 --- a/evm/go-x1/gossip/evmstore/evmpruner/pruner.go +++ /dev/null @@ -1,437 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmpruner - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "math" - "os" - "path/filepath" - "strings" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/state/snapshot" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" - - "github.com/Fantom-foundation/go-opera/gossip/evmstore" -) - -const ( - // stateBloomFilePrefix is the filename prefix of state bloom filter. - stateBloomFilePrefix = "statebloom" - - // stateBloomFilePrefix is the filename suffix of state bloom filter. - stateBloomFileSuffix = "bf.gz" - - // stateBloomFileTempSuffix is the filename suffix of state bloom filter - // while it is being written out to detect write aborts. - stateBloomFileTempSuffix = ".tmp" - - // rangeCompactionThreshold is the minimal deleted entry number for - // triggering range compaction. It's a quite arbitrary number but just - // to avoid triggering range compaction because of small deletion. - rangeCompactionThreshold = 100000 -) - -// Pruner is an offline tool to prune the stale state with the -// help of the snapshot. The workflow of pruner is very simple: -// -// - iterate the snapshot, reconstruct the relevant state -// - iterate the database, delete all other state entries which -// don't belong to the target state and the genesis state -// -// It can take several hours(around 2 hours for mainnet) to finish -// the whole pruning work. It's recommended to run this offline tool -// periodically in order to release the disk usage and improve the -// disk read performance to some extent. -type Pruner struct { - db ethdb.Database - stateBloom StateBloom - datadir string - root common.Hash - genesisRoot common.Hash - snaptree *snapshot.Tree -} - -type StateBloom interface { - ethdb.KeyValueWriter - Contain(key []byte) (bool, error) - Commit(filename, tempname string) error -} - -func NewProbabilisticSet(bloomSize uint64) (StateBloom, error) { - // Sanitize the bloom filter size if it's too small. - if bloomSize < 256 { - log.Warn("Sanitizing bloomfilter size", "provided(MB)", bloomSize, "updated(MB)", 256) - bloomSize = 256 - } - return newStateBloomWithSize(bloomSize) -} - -// NewPruner creates the pruner instance. -func NewPruner(db ethdb.Database, genesisRoot, root common.Hash, datadir string, stateBloom StateBloom) (*Pruner, error) { - snaptree, err := snapshot.New(db, trie.NewDatabase(db), 256, root, false, false, false) - if err != nil { - return nil, err // The relevant snapshot(s) might not exist - } - return &Pruner{ - db: db, - stateBloom: stateBloom, - datadir: datadir, - root: root, - genesisRoot: genesisRoot, - snaptree: snaptree, - }, nil -} - -func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, stateBloom StateBloom, bloomPath string, middleStateRoots map[common.Hash]struct{}, start time.Time) error { - // Delete all stale trie nodes in the disk. With the help of state bloom - // the trie nodes(and codes) belong to the active state will be filtered - // out. A very small part of stale tries will also be filtered because of - // the false-positive rate of bloom filter. But the assumption is held here - // that the false-positive is low enough(~0.05%). The probablity of the - // dangling node is the state root is super low. So the dangling nodes in - // theory will never ever be visited again. - var ( - count int - size common.StorageSize - pstart = time.Now() - logged = time.Now() - batch = maindb.NewBatch() - iter = maindb.NewIterator(nil, nil) - ) - for iter.Next() { - key := iter.Key() - - // All state entries don't belong to specific state and genesis are deleted here - // - trie node - // - legacy contract code - // - new-scheme contract code - isCode, codeKey := rawdb.IsCodeKey(key) - if len(key) == common.HashLength || isCode { - checkKey := key - if isCode { - checkKey = codeKey - } - if _, exist := middleStateRoots[common.BytesToHash(checkKey)]; exist { - log.Debug("Forcibly delete the middle state roots", "hash", common.BytesToHash(checkKey)) - } else { - if ok, err := stateBloom.Contain(checkKey); err != nil { - return err - } else if ok { - continue - } - } - count += 1 - size += common.StorageSize(len(key) + len(iter.Value())) - batch.Delete(key) - - var eta time.Duration // Realistically will never remain uninited - if done := binary.BigEndian.Uint64(key[:8]); done > 0 { - var ( - left = math.MaxUint64 - binary.BigEndian.Uint64(key[:8]) - speed = done/uint64(time.Since(pstart)/time.Millisecond+1) + 1 // +1s to avoid division by zero - ) - eta = time.Duration(left/speed) * time.Millisecond - } - if time.Since(logged) > 8*time.Second { - log.Info("Pruning state data", "nodes", count, "size", size, - "elapsed", common.PrettyDuration(time.Since(pstart)), "eta", common.PrettyDuration(eta)) - logged = time.Now() - } - // Recreate the iterator after every batch commit in order - // to allow the underlying compactor to delete the entries. - if batch.ValueSize() >= ethdb.IdealBatchSize { - batch.Write() - batch.Reset() - - iter.Release() - iter = maindb.NewIterator(nil, key) - } - } - } - if batch.ValueSize() > 0 { - batch.Write() - batch.Reset() - } - iter.Release() - log.Info("Pruned state data", "nodes", count, "size", size, "elapsed", common.PrettyDuration(time.Since(pstart))) - - // Secondly, flushing the snapshot journal into the disk. All diff - // layers upon are dropped silently. Eventually the entire snapshot - // tree is converted into a single disk layer with the pruning target - // as the root. - if _, err := snaptree.Journal(root); err != nil { - return err - } - // Delete the state bloom, it marks the entire pruning procedure is - // finished. If any crashes or manual exit happens before this, - // `RecoverPruning` will pick it up in the next restarts to redo all - // the things. - os.RemoveAll(bloomPath) - - // Start compactions, will remove the deleted data from the disk immediately. - // Note for small pruning, the compaction is skipped. - if count >= rangeCompactionThreshold { - cstart := time.Now() - for b := 0x00; b <= 0xf0; b += 0x10 { - var ( - start = []byte{byte(b)} - end = []byte{byte(b + 0x10)} - ) - if b == 0xf0 { - end = nil - } - log.Info("Compacting database", "range", fmt.Sprintf("%#x-%#x", start, end), "elapsed", common.PrettyDuration(time.Since(cstart))) - if err := maindb.Compact(start, end); err != nil { - log.Error("Database compaction failed", "error", err) - return err - } - } - log.Info("Database compaction finished", "elapsed", common.PrettyDuration(time.Since(cstart))) - } - log.Info("State pruning successful", "pruned", size, "elapsed", common.PrettyDuration(time.Since(start))) - return nil -} - -// Prune deletes all historical state nodes except the nodes belong to the -// specified state version. If user doesn't specify the state version, use -// the bottom-most snapshot diff layer as the target. -func (p *Pruner) Prune(root common.Hash) error { - // If the state bloom filter is already committed previously, - // reuse it for pruning instead of generating a new one. It's - // mandatory because a part of state may already be deleted, - // the recovery procedure is necessary. - _, stateBloomRoot, err := findBloomFilter(p.datadir) - if err != nil { - return err - } - if stateBloomRoot != (common.Hash{}) { - return RecoverPruning(p.datadir, p.db, p.root) - } - // If the target state root is not specified, use the HEAD-127 as the - // target. The reason for picking it is: - // - in most of the normal cases, the related state is available - // - the probability of this layer being reorg is very low - var layers []snapshot.Snapshot - if root == (common.Hash{}) { - // Retrieve all snapshot layers from the current HEAD. - // In theory there are 128 difflayers + 1 disk layer present, - // so 128 diff layers are expected to be returned. - layers = p.snaptree.Snapshots(p.root, 1, false) - if len(layers) <= 0 { - // Reject if the accumulated diff layers are less than 128. It - // means in most of normal cases, there is no associated state - // with bottom-most diff layer. - return fmt.Errorf("snapshot not old enough yet: need %d more blocks", 1) - } - // Use the bottom-most diff layer as the target - root = layers[len(layers)-1].Root() - } - - // All the state roots of the middle layer should be forcibly pruned, - // otherwise the dangling state will be left. - middleRoots := make(map[common.Hash]struct{}) - for _, layer := range layers { - if layer.Root() == root { - break - } - middleRoots[layer.Root()] = struct{}{} - } - // Traverse the target state, re-construct the whole state trie and - // commit to the given bloom filter. - start := time.Now() - if err := snapshot.GenerateTrie(p.snaptree, root, p.db, p.stateBloom); err != nil { - return err - } - // Traverse the genesis, put all genesis state entries into the - // bloom filter too. - if err := extractGenesis(p.db, p.genesisRoot, p.stateBloom); err != nil { - return err - } - filterName := bloomFilterName(p.datadir, root) - - if err := p.stateBloom.Commit(filterName, filterName+stateBloomFileTempSuffix); err != nil { - return err - } - return prune(p.snaptree, root, p.db, p.stateBloom, filterName, middleRoots, start) -} - -// RecoverPruning will resume the pruning procedure during the system restart. -// This function is used in this case: user tries to prune state data, but the -// system was interrupted midway because of crash or manual-kill. In this case -// if the bloom filter for filtering active state is already constructed, the -// pruning can be resumed. What's more if the bloom filter is constructed, the -// pruning **has to be resumed**. Otherwise a lot of dangling nodes may be left -// in the disk. -func RecoverPruning(datadir string, db ethdb.Database, root common.Hash) error { - stateBloomPath, stateBloomRoot, err := findBloomFilter(datadir) - if err != nil { - return err - } - if stateBloomPath == "" { - return nil // nothing to recover - } - // Initialize the snapshot tree in recovery mode to handle this special case: - // - Users run the `prune-state` command multiple times - // - Neither these `prune-state` running is finished(e.g. interrupted manually) - // - The state bloom filter is already generated, a part of state is deleted, - // so that resuming the pruning here is mandatory - // - The state HEAD is rewound already because of multiple incomplete `prune-state` - // In this case, even the state HEAD is not exactly matched with snapshot, it - // still feasible to recover the pruning correctly. - snaptree, err := snapshot.New(db, trie.NewDatabase(db), 256, root, false, false, true) - if err != nil { - return err // The relevant snapshot(s) might not exist - } - stateBloom, err := NewStateBloomFromDisk(stateBloomPath) - if err != nil { - return err - } - log.Info("Loaded state bloom filter", "path", stateBloomPath) - - // All the state roots of the middle layers should be forcibly pruned, - // otherwise the dangling state will be left. - var ( - found bool - layers = snaptree.Snapshots(root, 1, true) - middleRoots = make(map[common.Hash]struct{}) - ) - for _, layer := range layers { - if layer.Root() == stateBloomRoot { - found = true - break - } - middleRoots[layer.Root()] = struct{}{} - } - if !found { - log.Error("Pruning target state is not existent") - return errors.New("non-existent target state") - } - return prune(snaptree, stateBloomRoot, db, stateBloom, stateBloomPath, middleRoots, time.Now()) -} - -// extractGenesis loads the genesis state and commits all the state entries -// into the given bloomfilter. -func extractGenesis(db ethdb.Database, root common.Hash, stateBloom ethdb.KeyValueWriter) error { - if root == (common.Hash{}) { - return nil - } - t, err := trie.NewSecure(root, trie.NewDatabase(db)) - if err != nil { - return err - } - accIter := t.NodeIterator(nil) - for accIter.Next(true) { - hash := accIter.Hash() - - // Embedded nodes don't have hash. - if hash != (common.Hash{}) { - stateBloom.Put(hash.Bytes(), nil) - } - // If it's a leaf node, yes we are touching an account, - // dig into the storage trie further. - if accIter.Leaf() { - var acc state.Account - if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil { - return err - } - if acc.Root != types.EmptyRootHash { - storageTrie, err := trie.NewSecure(acc.Root, trie.NewDatabase(db)) - if err != nil { - return err - } - storageIter := storageTrie.NodeIterator(nil) - for storageIter.Next(true) { - hash := storageIter.Hash() - if hash != (common.Hash{}) { - stateBloom.Put(hash.Bytes(), nil) - } - } - if storageIter.Error() != nil { - return storageIter.Error() - } - } - if !bytes.Equal(acc.CodeHash, evmstore.EmptyCode) { - stateBloom.Put(acc.CodeHash, nil) - } - } - } - return accIter.Error() -} - -func bloomFilterName(datadir string, hash common.Hash) string { - return filepath.Join(datadir, fmt.Sprintf("%s.%s.%s", stateBloomFilePrefix, hash.Hex(), stateBloomFileSuffix)) -} - -func isBloomFilter(filename string) (bool, common.Hash) { - filename = filepath.Base(filename) - if strings.HasPrefix(filename, stateBloomFilePrefix) && strings.HasSuffix(filename, stateBloomFileSuffix) { - return true, common.HexToHash(filename[len(stateBloomFilePrefix)+1 : len(filename)-len(stateBloomFileSuffix)-1]) - } - return false, common.Hash{} -} - -func findBloomFilter(datadir string) (string, common.Hash, error) { - var ( - stateBloomPath string - stateBloomRoot common.Hash - ) - if err := filepath.Walk(datadir, func(path string, info os.FileInfo, err error) error { - if info != nil && !info.IsDir() { - ok, root := isBloomFilter(path) - if ok { - stateBloomPath = path - stateBloomRoot = root - } - } - return nil - }); err != nil { - return "", common.Hash{}, err - } - return stateBloomPath, stateBloomRoot, nil -} - -const warningLog = ` - -WARNING! - -The clean trie cache is not found. Please delete it by yourself after the -pruning. Remember don't start the Geth without deleting the clean trie cache -otherwise the entire database may be damaged! - -Check the command description "geth snapshot prune-state --help" for more details. -` - -func deleteCleanTrieCache(path string) { - if _, err := os.Stat(path); os.IsNotExist(err) { - log.Warn(warningLog) - return - } - os.RemoveAll(path) - log.Info("Deleted trie clean cache", "path", path) -} diff --git a/evm/go-x1/gossip/evmstore/store.go b/evm/go-x1/gossip/evmstore/store.go deleted file mode 100644 index 68f69c1..0000000 --- a/evm/go-x1/gossip/evmstore/store.go +++ /dev/null @@ -1,304 +0,0 @@ -package evmstore - -import ( - "errors" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/nokeyiserr" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" - "github.com/Fantom-foundation/lachesis-base/utils/wlru" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/prque" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/state/snapshot" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/trie" - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/topicsdb" - "github.com/Fantom-foundation/go-opera/utils/adapters/kvdb2ethdb" - "github.com/Fantom-foundation/go-opera/utils/rlpstore" -) - -const nominalSize uint = 1 - -// Store is a node persistent storage working over physical key-value database. -type Store struct { - cfg StoreConfig - - table struct { - Evm kvdb.Store `table:"M"` - // API-only tables - Receipts kvdb.Store `table:"r"` - TxPositions kvdb.Store `table:"x"` - Txs kvdb.Store `table:"X"` - } - - EvmDb ethdb.Database - EvmState state.Database - EvmLogs topicsdb.Index - Snaps *snapshot.Tree - - cache struct { - TxPositions *wlru.Cache `cache:"-"` // store by pointer - Receipts *wlru.Cache `cache:"-"` // store by value - EvmBlocks *wlru.Cache `cache:"-"` // store by pointer - } - - rlp rlpstore.Helper - - triegc *prque.Prque // Priority queue mapping block numbers to tries to gc - - logger.Instance -} - -const ( - TriesInMemory = 16 -) - -// NewStore creates store over key-value db. -func NewStore(dbs kvdb.DBProducer, cfg StoreConfig) *Store { - s := &Store{ - cfg: cfg, - Instance: logger.New("evm-store"), - rlp: rlpstore.Helper{logger.New("rlp")}, - triegc: prque.New(nil), - } - - err := table.OpenTables(&s.table, dbs, "evm") - if err != nil { - s.Log.Crit("Failed to open tables", "err", err) - } - - s.initEVMDB() - s.EvmLogs = topicsdb.NewWithThreadPool(dbs) - s.initCache() - - return s -} - -// Close closes underlying database. -func (s *Store) Close() { - setnil := func() interface{} { - return nil - } - - _ = table.CloseTables(&s.table) - table.MigrateTables(&s.table, nil) - table.MigrateCaches(&s.cache, setnil) - s.EvmLogs.Close() -} - -func (s *Store) initCache() { - s.cache.Receipts = s.makeCache(s.cfg.Cache.ReceiptsSize, s.cfg.Cache.ReceiptsBlocks) - s.cache.TxPositions = s.makeCache(nominalSize*uint(s.cfg.Cache.TxPositions), s.cfg.Cache.TxPositions) - s.cache.EvmBlocks = s.makeCache(s.cfg.Cache.EvmBlocksSize, s.cfg.Cache.EvmBlocksNum) -} - -func (s *Store) initEVMDB() { - s.EvmDb = rawdb.NewDatabase( - kvdb2ethdb.Wrap( - nokeyiserr.Wrap( - s.table.Evm))) - s.EvmState = state.NewDatabaseWithConfig(s.EvmDb, &trie.Config{ - Cache: s.cfg.Cache.EvmDatabase / opt.MiB, - Journal: s.cfg.Cache.TrieCleanJournal, - Preimages: s.cfg.EnablePreimageRecording, - GreedyGC: s.cfg.Cache.GreedyGC, - }) -} - -func (s *Store) ResetWithEVMDB(evmStore kvdb.Store) *Store { - cp := *s - cp.table.Evm = evmStore - cp.initEVMDB() - cp.Snaps = nil - return &cp -} - -func (s *Store) EVMDB() kvdb.Store { - return s.table.Evm -} - -func (s *Store) GenerateEvmSnapshot(root common.Hash, rebuild, async bool) (err error) { - if s.Snaps != nil { - return errors.New("EVM snapshot is already opened") - } - s.Snaps, err = snapshot.New( - s.EvmDb, - s.EvmState.TrieDB(), - s.cfg.Cache.EvmSnap/opt.MiB, - root, - async, - rebuild, - false) - return -} - -func (s *Store) RebuildEvmSnapshot(root common.Hash) { - if s.Snaps == nil { - return - } - s.Snaps.Rebuild(root) -} - -// CleanCommit clean old state trie and commit changes. -func (s *Store) CleanCommit(block iblockproc.BlockState) error { - // Don't need to reference the current state root - // due to it already be referenced on `Commit()` function - triedb := s.EvmState.TrieDB() - stateRoot := common.Hash(block.FinalizedStateRoot) - if current := uint64(block.LastBlock.Idx); current > TriesInMemory { - // Find the next state trie we need to commit - chosen := current - TriesInMemory - // Garbage collect all below the chosen block - for !s.triegc.Empty() { - root, number := s.triegc.Pop() - if uint64(-number) > chosen { - s.triegc.Push(root, number) - break - } - triedb.Dereference(root.(common.Hash)) - } - } - // commit the state trie after clean up - err := triedb.Commit(stateRoot, false, nil) - if err != nil { - s.Log.Error("Failed to flush trie DB into main DB", "err", err) - } - return err -} - -func (s *Store) PauseEvmSnapshot() { - s.Snaps.Disable() -} - -func (s *Store) IsEvmSnapshotPaused() bool { - return rawdb.ReadSnapshotDisabled(s.table.Evm) -} - -// Commit changes. -func (s *Store) Commit(block idx.Block, root hash.Hash, flush bool) error { - triedb := s.EvmState.TrieDB() - stateRoot := common.Hash(root) - // If we're applying genesis or running an archive node, always flush - if flush || s.cfg.Cache.TrieDirtyDisabled { - err := triedb.Commit(stateRoot, false, nil) - if err != nil { - s.Log.Error("Failed to flush trie DB into main DB", "err", err) - } - return err - } else { - // Full but not archive node, do proper garbage collection - triedb.Reference(stateRoot, common.Hash{}) // metadata reference to keep trie alive - s.triegc.Push(stateRoot, -int64(block)) - - if current := uint64(block); current > TriesInMemory { - // If we exceeded our memory allowance, flush matured singleton nodes to disk - s.Cap() - - // Find the next state trie we need to commit - chosen := current - TriesInMemory - - // Garbage collect all below the chosen block - for !s.triegc.Empty() { - root, number := s.triegc.Pop() - if uint64(-number) > chosen { - s.triegc.Push(root, number) - break - } - triedb.Dereference(root.(common.Hash)) - } - } - return nil - } -} - -func (s *Store) Flush(block iblockproc.BlockState) { - // Ensure that the entirety of the state snapshot is journalled to disk. - var snapBase common.Hash - if s.Snaps != nil { - var err error - if snapBase, err = s.Snaps.Journal(common.Hash(block.FinalizedStateRoot)); err != nil { - s.Log.Error("Failed to journal state snapshot", "err", err) - } - } - // Ensure the state of a recent block is also stored to disk before exiting. - if !s.cfg.Cache.TrieDirtyDisabled { - triedb := s.EvmState.TrieDB() - - if number := uint64(block.LastBlock.Idx); number > 0 { - s.Log.Info("Writing cached state to disk", "block", number, "root", block.FinalizedStateRoot) - if err := triedb.Commit(common.Hash(block.FinalizedStateRoot), true, nil); err != nil { - s.Log.Error("Failed to commit recent state trie", "err", err) - } - } - if snapBase != (common.Hash{}) { - s.Log.Info("Writing snapshot state to disk", "root", snapBase) - if err := triedb.Commit(snapBase, true, nil); err != nil { - s.Log.Error("Failed to commit recent state trie", "err", err) - } - } - } - // Ensure all live cached entries be saved into disk, so that we can skip - // cache warmup when node restarts. - if s.cfg.Cache.TrieCleanJournal != "" { - triedb := s.EvmState.TrieDB() - triedb.SaveCache(s.cfg.Cache.TrieCleanJournal) - } -} - -// Cap flush matured singleton nodes to disk -func (s *Store) Cap() { - triedb := s.EvmState.TrieDB() - var ( - nodes, imgs = triedb.Size() - limit = common.StorageSize(s.cfg.Cache.TrieDirtyLimit) - ) - // If we exceeded our memory allowance, flush matured singleton nodes to disk - if nodes > limit+ethdb.IdealBatchSize || imgs > 4*1024*1024 { - triedb.Cap(limit) - } -} - -// StateDB returns state database. -func (s *Store) StateDB(from hash.Hash) (*state.StateDB, error) { - return state.NewWithSnapLayers(common.Hash(from), s.EvmState, s.Snaps, 0) -} - -// HasStateDB returns if state database exists -func (s *Store) HasStateDB(from hash.Hash) bool { - _, err := s.StateDB(from) - return err == nil -} - -// IndexLogs indexes EVM logs -func (s *Store) IndexLogs(recs ...*types.Log) { - err := s.EvmLogs.Push(recs...) - if err != nil { - s.Log.Crit("DB logs index error", "err", err) - } -} - -func (s *Store) Snapshots() *snapshot.Tree { - return s.Snaps -} - -/* - * Utils: - */ - -func (s *Store) makeCache(weight uint, size int) *wlru.Cache { - cache, err := wlru.New(weight, size) - if err != nil { - s.Log.Crit("Failed to create LRU cache", "err", err) - return nil - } - return cache -} diff --git a/evm/go-x1/gossip/evmstore/store_block_cache.go b/evm/go-x1/gossip/evmstore/store_block_cache.go deleted file mode 100644 index fd95551..0000000 --- a/evm/go-x1/gossip/evmstore/store_block_cache.go +++ /dev/null @@ -1,25 +0,0 @@ -package evmstore - -import ( - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - - "github.com/Fantom-foundation/go-opera/evmcore" -) - -func (s *Store) GetCachedEvmBlock(n idx.Block) *evmcore.EvmBlock { - c, ok := s.cache.EvmBlocks.Get(n) - if !ok { - return nil - } - - return c.(*evmcore.EvmBlock) -} - -func (s *Store) SetCachedEvmBlock(n idx.Block, b *evmcore.EvmBlock) { - var empty = common.Hash{} - if b.EvmHeader.TxHash == empty { - panic("You have to cache only completed blocks (with txs)") - } - s.cache.EvmBlocks.Add(n, b, uint(b.EstimateSize())) -} diff --git a/evm/go-x1/gossip/evmstore/store_receipts.go b/evm/go-x1/gossip/evmstore/store_receipts.go deleted file mode 100644 index 0e8caf7..0000000 --- a/evm/go-x1/gossip/evmstore/store_receipts.go +++ /dev/null @@ -1,95 +0,0 @@ -package evmstore - -/* - In LRU cache data stored like value -*/ - -import ( - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" -) - -// SetReceipts stores transaction receipts. -func (s *Store) SetReceipts(n idx.Block, receipts types.Receipts) { - receiptsStorage := make([]*types.ReceiptForStorage, receipts.Len()) - for i, r := range receipts { - receiptsStorage[i] = (*types.ReceiptForStorage)(r) - } - - size := s.SetRawReceipts(n, receiptsStorage) - - // Add to LRU cache. - s.cache.Receipts.Add(n, receipts, uint(size)) -} - -// SetRawReceipts stores raw transaction receipts. -func (s *Store) SetRawReceipts(n idx.Block, receipts []*types.ReceiptForStorage) (size int) { - buf, err := rlp.EncodeToBytes(receipts) - if err != nil { - s.Log.Crit("Failed to encode rlp", "err", err) - } - - if err := s.table.Receipts.Put(n.Bytes(), buf); err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } - - // Remove from LRU cache. - s.cache.Receipts.Remove(n) - - return len(buf) -} - -func (s *Store) GetRawReceiptsRLP(n idx.Block) rlp.RawValue { - buf, err := s.table.Receipts.Get(n.Bytes()) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - return buf -} - -func (s *Store) GetRawReceipts(n idx.Block) ([]*types.ReceiptForStorage, int) { - buf := s.GetRawReceiptsRLP(n) - if buf == nil { - return nil, 0 - } - - var receiptsStorage []*types.ReceiptForStorage - err := rlp.DecodeBytes(buf, &receiptsStorage) - if err != nil { - s.Log.Crit("Failed to decode rlp", "err", err, "size", len(buf)) - } - return receiptsStorage, len(buf) -} - -func UnwrapStorageReceipts(receiptsStorage []*types.ReceiptForStorage, n idx.Block, signer types.Signer, hash common.Hash, txs types.Transactions) (types.Receipts, error) { - receipts := make(types.Receipts, len(receiptsStorage)) - for i, r := range receiptsStorage { - receipts[i] = (*types.Receipt)(r) - } - err := receipts.DeriveFields(signer, hash, uint64(n), txs) - return receipts, err -} - -// GetReceipts returns stored transaction receipts. -func (s *Store) GetReceipts(n idx.Block, signer types.Signer, hash common.Hash, txs types.Transactions) types.Receipts { - // Get data from LRU cache first. - if s.cache.Receipts != nil { - if c, ok := s.cache.Receipts.Get(n); ok { - return c.(types.Receipts) - } - } - - receiptsStorage, size := s.GetRawReceipts(n) - - receipts, err := UnwrapStorageReceipts(receiptsStorage, n, signer, hash, txs) - if err != nil { - s.Log.Crit("Failed to derive receipts", "err", err) - } - - // Add to LRU cache. - s.cache.Receipts.Add(n, receipts, uint(size)) - - return receipts -} diff --git a/evm/go-x1/gossip/evmstore/store_receipts_test.go b/evm/go-x1/gossip/evmstore/store_receipts_test.go deleted file mode 100644 index 479cb87..0000000 --- a/evm/go-x1/gossip/evmstore/store_receipts_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package evmstore - -import ( - "testing" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/assert" - - "github.com/Fantom-foundation/go-opera/logger" -) - -func equalStorageReceipts(t *testing.T, expect, got []*types.ReceiptForStorage) { - assert.EqualValues(t, len(expect), len(got)) - for i := range expect { - assert.EqualValues(t, expect[i].CumulativeGasUsed, got[i].CumulativeGasUsed) - assert.EqualValues(t, expect[i].Logs, got[i].Logs) - assert.EqualValues(t, expect[i].Status, got[i].Status) - } -} - -func TestStoreGetCachedReceipts(t *testing.T) { - logger.SetTestMode(t) - - block, expect := fakeReceipts() - store := cachedStore() - store.SetRawReceipts(block, expect) - - got, _ := store.GetRawReceipts(block) - assert.EqualValues(t, expect, got) -} - -func TestStoreGetNonCachedReceipts(t *testing.T) { - logger.SetTestMode(t) - - block, expect := fakeReceipts() - store := nonCachedStore() - store.SetRawReceipts(block, expect) - - got, _ := store.GetRawReceipts(block) - equalStorageReceipts(t, expect, got) -} - -func BenchmarkStoreGetRawReceipts(b *testing.B) { - logger.SetTestMode(b) - - b.Run("cache on", func(b *testing.B) { - benchStoreGetRawReceipts(b, cachedStore()) - }) - b.Run("cache off", func(b *testing.B) { - benchStoreGetRawReceipts(b, nonCachedStore()) - }) -} - -func benchStoreGetRawReceipts(b *testing.B, store *Store) { - block, receipt := fakeReceipts() - - store.SetRawReceipts(block, receipt) - b.ResetTimer() - - for i := 0; i < b.N; i++ { - if v, _ := store.GetRawReceipts(block); v == nil { - b.Fatal("invalid result") - } - } -} - -func BenchmarkStoreSetRawReceipts(b *testing.B) { - logger.SetTestMode(b) - - b.Run("cache on", func(b *testing.B) { - benchStoreSetRawReceipts(b, cachedStore()) - }) - b.Run("cache off", func(b *testing.B) { - benchStoreSetRawReceipts(b, nonCachedStore()) - }) -} - -func benchStoreSetRawReceipts(b *testing.B, store *Store) { - block, receipt := fakeReceipts() - - for i := 0; i < b.N; i++ { - store.SetRawReceipts(block, receipt) - } -} - -func fakeReceipts() (idx.Block, []*types.ReceiptForStorage) { - return idx.Block(1), - []*types.ReceiptForStorage{ - { - PostState: nil, - Status: 0, - CumulativeGasUsed: 0, - Bloom: types.Bloom{}, - Logs: []*types.Log{}, - TxHash: common.Hash{}, - ContractAddress: common.Address{}, - GasUsed: 0, - BlockHash: common.Hash{}, - BlockNumber: nil, - TransactionIndex: 0, - }, - } -} diff --git a/evm/go-x1/gossip/evmstore/store_test.go b/evm/go-x1/gossip/evmstore/store_test.go deleted file mode 100644 index 736a433..0000000 --- a/evm/go-x1/gossip/evmstore/store_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package evmstore - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" -) - -func cachedStore() *Store { - cfg := LiteStoreConfig() - - return NewStore(memorydb.NewProducer(""), cfg) -} - -func nonCachedStore() *Store { - cfg := StoreConfig{} - - return NewStore(memorydb.NewProducer(""), cfg) -} diff --git a/evm/go-x1/gossip/evmstore/store_tx.go b/evm/go-x1/gossip/evmstore/store_tx.go deleted file mode 100644 index 6a664e6..0000000 --- a/evm/go-x1/gossip/evmstore/store_tx.go +++ /dev/null @@ -1,59 +0,0 @@ -package evmstore - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - - "github.com/Fantom-foundation/go-opera/inter" -) - -// SetTx stores non-event transaction. -func (s *Store) SetTx(txid common.Hash, tx *types.Transaction) { - s.rlp.Set(s.table.Txs, txid.Bytes(), tx) -} - -// GetTx returns stored non-event transaction. -func (s *Store) GetTx(txid common.Hash) *types.Transaction { - tx, _ := s.rlp.Get(s.table.Txs, txid.Bytes(), &types.Transaction{}).(*types.Transaction) - - return tx -} - -func (s *Store) GetBlockTxs(n idx.Block, block inter.Block, getEventPayload func(hash.Event) *inter.EventPayload) types.Transactions { - if cached := s.GetCachedEvmBlock(n); cached != nil { - return cached.Transactions - } - - transactions := make(types.Transactions, 0, len(block.Txs)+len(block.InternalTxs)+len(block.Events)*10) - for _, txid := range block.InternalTxs { - tx := s.GetTx(txid) - if tx == nil { - log.Crit("Internal tx not found", "tx", txid.String()) - continue - } - transactions = append(transactions, tx) - } - for _, txid := range block.Txs { - tx := s.GetTx(txid) - if tx == nil { - log.Crit("Tx not found", "tx", txid.String()) - continue - } - transactions = append(transactions, tx) - } - for _, id := range block.Events { - e := getEventPayload(id) - if e == nil { - log.Crit("Block event not found", "event", id.String()) - continue - } - transactions = append(transactions, e.Txs()...) - } - - transactions = inter.FilterSkippedTxs(transactions, block.SkippedTxs) - - return transactions -} diff --git a/evm/go-x1/gossip/evmstore/store_tx_position.go b/evm/go-x1/gossip/evmstore/store_tx_position.go deleted file mode 100644 index ee4fcc4..0000000 --- a/evm/go-x1/gossip/evmstore/store_tx_position.go +++ /dev/null @@ -1,45 +0,0 @@ -package evmstore - -/* - In LRU cache data stored like pointer -*/ - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" -) - -type TxPosition struct { - Block idx.Block - Event hash.Event - EventOffset uint32 - BlockOffset uint32 -} - -// SetTxPosition stores transaction block and position. -func (s *Store) SetTxPosition(txid common.Hash, position TxPosition) { - s.rlp.Set(s.table.TxPositions, txid.Bytes(), &position) - - // Add to LRU cache. - s.cache.TxPositions.Add(txid.String(), &position, nominalSize) -} - -// GetTxPosition returns stored transaction block and position. -func (s *Store) GetTxPosition(txid common.Hash) *TxPosition { - // Get data from LRU cache first. - if c, ok := s.cache.TxPositions.Get(txid.String()); ok { - if b, ok := c.(*TxPosition); ok { - return b - } - } - - txPosition, _ := s.rlp.Get(s.table.TxPositions, txid.Bytes(), &TxPosition{}).(*TxPosition) - - // Add to LRU cache. - if txPosition != nil { - s.cache.TxPositions.Add(txid.String(), txPosition, nominalSize) - } - - return txPosition -} diff --git a/evm/go-x1/gossip/evmstore/utils.go b/evm/go-x1/gossip/evmstore/utils.go deleted file mode 100644 index 5b9a65c..0000000 --- a/evm/go-x1/gossip/evmstore/utils.go +++ /dev/null @@ -1,210 +0,0 @@ -package evmstore - -import ( - "bytes" - "errors" - "fmt" - "io" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" - "github.com/Fantom-foundation/lachesis-base/utils/simplewlru" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/utils/iodb" -) - -var ( - // EmptyCode is the known hash of the empty EVM bytecode. - EmptyCode = crypto.Keccak256(nil) - - emptyCodeHash = common.BytesToHash(EmptyCode) - emptyHash = common.Hash{} -) - -func (s *Store) CheckEvm(forEachState func(func(root common.Hash) (found bool, err error)), onlyRoots bool) error { - log.Info("Checking every node hash") - nodeIt := s.table.Evm.NewIterator(nil, nil) - defer nodeIt.Release() - for nodeIt.Next() { - if len(nodeIt.Key()) != 32 { - continue - } - calcHash := crypto.Keccak256(nodeIt.Value()) - if !bytes.Equal(nodeIt.Key(), calcHash) { - log.Crit("Malformed node record", "exp", common.Bytes2Hex(calcHash), "got", common.Bytes2Hex(nodeIt.Key())) - } - } - - log.Info("Checking every code hash") - codeIt := table.New(s.table.Evm, []byte("c")).NewIterator(nil, nil) - defer codeIt.Release() - for codeIt.Next() { - if len(codeIt.Key()) != 32 { - continue - } - calcHash := crypto.Keccak256(codeIt.Value()) - if !bytes.Equal(codeIt.Key(), calcHash) { - log.Crit("Malformed code record", "exp", common.Bytes2Hex(calcHash), "got", common.Bytes2Hex(codeIt.Key())) - } - } - - log.Info("Checking every preimage") - preimageIt := table.New(s.table.Evm, []byte("secure-key-")).NewIterator(nil, nil) - defer preimageIt.Release() - for preimageIt.Next() { - if len(preimageIt.Key()) != 32 { - continue - } - calcHash := crypto.Keccak256(preimageIt.Value()) - if !bytes.Equal(preimageIt.Key(), calcHash) { - log.Crit("Malformed preimage record", "exp", common.Bytes2Hex(calcHash), "got", common.Bytes2Hex(preimageIt.Key())) - } - } - - if onlyRoots { - log.Info("Checking presence of every root") - } else { - log.Info("Checking presence of every node") - } - var ( - visitedHashes = make([]common.Hash, 0, 1000000) - visitedI = 0 - checkedCache, _ = simplewlru.New(100000000, 100000000) - cached = func(h common.Hash) bool { - _, ok := checkedCache.Get(h) - return ok - } - ) - visited := func(h common.Hash, priority int) { - base := 100000 * priority - if visitedI%(1<<(len(visitedHashes)/base)) == 0 { - visitedHashes = append(visitedHashes, h) - } - visitedI++ - } - forEachState(func(root common.Hash) (found bool, err error) { - stateTrie, err := s.EvmState.OpenTrie(root) - found = stateTrie != nil && err == nil - if !found || onlyRoots { - return - } - - // check existence of every code hash and root of every storage trie - stateIt := stateTrie.NodeIterator(nil) - for stateItSkip := false; stateIt.Next(!stateItSkip); { - stateItSkip = false - if stateIt.Hash() != emptyHash { - if cached(stateIt.Hash()) { - stateItSkip = true - continue - } - visited(stateIt.Hash(), 2) - } - - if stateIt.Leaf() { - addrHash := common.BytesToHash(stateIt.LeafKey()) - - var account state.Account - if err = rlp.Decode(bytes.NewReader(stateIt.LeafBlob()), &account); err != nil { - err = fmt.Errorf("Failed to decode accoun as %s addr: %s", addrHash.String(), err.Error()) - return - } - - codeHash := common.BytesToHash(account.CodeHash) - if codeHash != emptyCodeHash && !cached(codeHash) { - code, _ := s.EvmState.ContractCode(addrHash, codeHash) - if code == nil { - err = fmt.Errorf("failed to get code %s at %s addr", codeHash.String(), addrHash.String()) - return - } - checkedCache.Add(codeHash, true, 1) - } - - if account.Root != types.EmptyRootHash && !cached(account.Root) { - storageTrie, storageErr := s.EvmState.OpenStorageTrie(addrHash, account.Root) - if storageErr != nil { - err = fmt.Errorf("failed to open storage trie %s at %s addr: %s", account.Root.String(), addrHash.String(), storageErr.Error()) - return - } - storageIt := storageTrie.NodeIterator(nil) - for storageItSkip := false; storageIt.Next(!storageItSkip); { - storageItSkip = false - if storageIt.Hash() != emptyHash { - if cached(storageIt.Hash()) { - storageItSkip = true - continue - } - visited(storageIt.Hash(), 1) - } - } - if storageIt.Error() != nil { - err = fmt.Errorf("EVM storage trie %s at %s addr iteration error: %s", account.Root.String(), addrHash.String(), storageIt.Error()) - return - } - } - } - } - - if stateIt.Error() != nil { - err = fmt.Errorf("EVM state trie %s iteration error: %s", root.String(), stateIt.Error()) - return - } - for _, h := range visitedHashes { - checkedCache.Add(h, true, 1) - } - visitedHashes = visitedHashes[:0] - - return - }) - - return nil -} - -func (s *Store) ImportEvm(r io.Reader) error { - it := iodb.NewIterator(r) - defer it.Release() - batch := &restrictedEvmBatch{s.table.Evm.NewBatch()} - defer batch.Reset() - for it.Next() { - err := batch.Put(it.Key(), it.Value()) - if err != nil { - return err - } - if batch.ValueSize() > kvdb.IdealBatchSize { - err := batch.Write() - if err != nil { - return err - } - batch.Reset() - } - } - return batch.Write() -} - -type restrictedEvmBatch struct { - kvdb.Batch -} - -func IsMptKey(key []byte) bool { - return len(key) == common.HashLength || - (bytes.HasPrefix(key, rawdb.CodePrefix) && len(key) == len(rawdb.CodePrefix)+common.HashLength) -} - -func IsPreimageKey(key []byte) bool { - preimagePrefix := []byte("secure-key-") - return bytes.HasPrefix(key, preimagePrefix) && len(key) == (len(preimagePrefix)+common.HashLength) -} - -func (v *restrictedEvmBatch) Put(key []byte, value []byte) error { - if !IsMptKey(key) && !IsPreimageKey(key) { - return errors.New("not expected prefix for EVM history dump") - } - return v.Batch.Put(key, value) -} diff --git a/evm/go-x1/gossip/execqueue.go b/evm/go-x1/gossip/execqueue.go deleted file mode 100644 index 38e251d..0000000 --- a/evm/go-x1/gossip/execqueue.go +++ /dev/null @@ -1,88 +0,0 @@ -package gossip - -import "sync" - -// execQueue implements a queue that executes function calls in a single thread, -// in the same order as they have been queued. -type execQueue struct { - mu sync.Mutex - cond *sync.Cond - funcs []func() - closeWait chan struct{} -} - -// newExecQueue creates a new execution queue. -func newExecQueue(capacity int) *execQueue { - q := &execQueue{funcs: make([]func(), 0, capacity)} - q.cond = sync.NewCond(&q.mu) - go q.loop() - return q -} - -func (q *execQueue) loop() { - for f := q.waitNext(false); f != nil; f = q.waitNext(true) { - f() - } - close(q.closeWait) -} - -func (q *execQueue) waitNext(drop bool) (f func()) { - q.mu.Lock() - if drop && len(q.funcs) > 0 { - // Remove the function that just executed. We do this here instead of when - // dequeuing so len(q.funcs) includes the function that is running. - q.funcs = append(q.funcs[:0], q.funcs[1:]...) - } - for !q.isClosed() { - if len(q.funcs) > 0 { - f = q.funcs[0] - break - } - q.cond.Wait() - } - q.mu.Unlock() - return f -} - -func (q *execQueue) isClosed() bool { - return q.closeWait != nil -} - -// canQueue returns true if more function calls can be added to the execution queue. -func (q *execQueue) canQueue() bool { - q.mu.Lock() - ok := !q.isClosed() && len(q.funcs) < cap(q.funcs) - q.mu.Unlock() - return ok -} - -// queue adds a function call to the execution queue. Returns true if successful. -func (q *execQueue) queue(f func()) bool { - q.mu.Lock() - ok := !q.isClosed() && len(q.funcs) < cap(q.funcs) - if ok { - q.funcs = append(q.funcs, f) - q.cond.Signal() - } - q.mu.Unlock() - return ok -} - -// clear drops all queued functions -func (q *execQueue) clear() { - q.mu.Lock() - q.funcs = q.funcs[:0] - q.mu.Unlock() -} - -// quit stops the exec queue. -// quit waits for the current execution to finish before returning. -func (q *execQueue) quit() { - q.mu.Lock() - if !q.isClosed() { - q.closeWait = make(chan struct{}) - q.cond.Signal() - } - q.mu.Unlock() - <-q.closeWait -} diff --git a/evm/go-x1/gossip/filters/api.go b/evm/go-x1/gossip/filters/api.go deleted file mode 100644 index 89e20e3..0000000 --- a/evm/go-x1/gossip/filters/api.go +++ /dev/null @@ -1,600 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package filters - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "math/big" - "sync" - "time" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rpc" -) - -var ( - deadline = 5 * time.Minute // consider a filter inactive if it has not been polled for within deadline -) - -// filter is a helper struct that holds meta information over the filter type -// and associated subscription in the event system. -type filter struct { - typ Type - deadline *time.Timer // filter is inactiv when deadline triggers - hashes []common.Hash - crit FilterCriteria - logs []*types.Log - s *Subscription // associated subscription in event system -} - -// Config is a provided API params. -type Config struct { - // Block range limit for logs search (indexed). - IndexedLogsBlockRangeLimit idx.Block - // Block range limit for logs search (unindexed). - UnindexedLogsBlockRangeLimit idx.Block -} - -func DefaultConfig() Config { - return Config{ - IndexedLogsBlockRangeLimit: 999999999999999999, - UnindexedLogsBlockRangeLimit: 100, - } -} - -// PublicFilterAPI offers support to create and manage filters. This will allow external clients to retrieve various -// information related to the Ethereum protocol such als blocks, transactions and logs. -type PublicFilterAPI struct { - config Config - backend Backend - chainDb ethdb.Database - events *EventSystem - filtersMu sync.Mutex - filters map[rpc.ID]*filter -} - -// NewPublicFilterAPI returns a new PublicFilterAPI instance. -func NewPublicFilterAPI(backend Backend, cfg Config) *PublicFilterAPI { - api := &PublicFilterAPI{ - config: cfg, - backend: backend, - chainDb: backend.ChainDb(), - events: NewEventSystem(backend), - filters: make(map[rpc.ID]*filter), - } - go api.timeoutLoop(5 * time.Minute) - - return api -} - -// timeoutLoop runs at the interval set by 'timeout' and deletes filters -// that have not been recently used. It is started when the API is created. -func (api *PublicFilterAPI) timeoutLoop(timeout time.Duration) { - var toUninstall []*Subscription - ticker := time.NewTicker(timeout) - defer ticker.Stop() - for { - <-ticker.C - api.filtersMu.Lock() - for id, f := range api.filters { - select { - case <-f.deadline.C: - toUninstall = append(toUninstall, f.s) - delete(api.filters, id) - default: - continue - } - } - api.filtersMu.Unlock() - - // Unsubscribes are processed outside the lock to avoid the following scenario: - // event loop attempts broadcasting events to still active filters while - // Unsubscribe is waiting for it to process the uninstall request. - for _, s := range toUninstall { - s.Unsubscribe() - } - toUninstall = nil - } -} - -// NewPendingTransactionFilter creates a filter that fetches pending transaction hashes -// as transactions enter the pending state. -// -// It is part of the filter package because this filter can be used through the -// `eth_getFilterChanges` polling method that is also used for log filters. -// -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newpendingtransactionfilter -func (api *PublicFilterAPI) NewPendingTransactionFilter() rpc.ID { - var ( - pendingTxs = make(chan []common.Hash) - pendingTxSub = api.events.SubscribePendingTxs(pendingTxs) - ) - - api.filtersMu.Lock() - api.filters[pendingTxSub.ID] = &filter{typ: PendingTransactionsSubscription, deadline: time.NewTimer(deadline), hashes: make([]common.Hash, 0), s: pendingTxSub} - api.filtersMu.Unlock() - - go func() { - for { - select { - case ph := <-pendingTxs: - api.filtersMu.Lock() - if f, found := api.filters[pendingTxSub.ID]; found { - f.hashes = append(f.hashes, ph...) - } - api.filtersMu.Unlock() - case <-pendingTxSub.Err(): - api.filtersMu.Lock() - delete(api.filters, pendingTxSub.ID) - api.filtersMu.Unlock() - return - } - } - }() - - return pendingTxSub.ID -} - -// NewPendingTransactions creates a subscription that is triggered each time a transaction -// enters the transaction pool and was signed from one of the transactions this nodes manages. -func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context) (*rpc.Subscription, error) { - notifier, supported := rpc.NotifierFromContext(ctx) - if !supported { - return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported - } - - rpcSub := notifier.CreateSubscription() - - go func() { - txHashes := make(chan []common.Hash, 128) - pendingTxSub := api.events.SubscribePendingTxs(txHashes) - - for { - select { - case hashes := <-txHashes: - // To keep the original behaviour, send a single tx hash in one notification. - // TODO(rjl493456442) Send a batch of tx hashes in one notification - for _, h := range hashes { - _ = notifier.Notify(rpcSub.ID, h) - } - case <-rpcSub.Err(): - pendingTxSub.Unsubscribe() - return - case <-notifier.Closed(): - pendingTxSub.Unsubscribe() - return - } - } - }() - - return rpcSub, nil -} - -// NewBlockFilter creates a filter that fetches blocks that are imported into the chain. -// It is part of the filter package since polling goes with eth_getFilterChanges. -// -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newblockfilter -func (api *PublicFilterAPI) NewBlockFilter() rpc.ID { - var ( - headers = make(chan *types.Header) - headerSub = api.events.SubscribeNewHeads(headers) - ) - - api.filtersMu.Lock() - api.filters[headerSub.ID] = &filter{typ: BlocksSubscription, deadline: time.NewTimer(deadline), hashes: make([]common.Hash, 0), s: headerSub} - api.filtersMu.Unlock() - - go func() { - for { - select { - case h := <-headers: - api.filtersMu.Lock() - if f, found := api.filters[headerSub.ID]; found { - f.hashes = append(f.hashes, h.Hash()) - } - api.filtersMu.Unlock() - case <-headerSub.Err(): - api.filtersMu.Lock() - delete(api.filters, headerSub.ID) - api.filtersMu.Unlock() - return - } - } - }() - - return headerSub.ID -} - -// NewHeads send a notification each time a new (header) block is appended to the chain. -func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, error) { - notifier, supported := rpc.NotifierFromContext(ctx) - if !supported { - return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported - } - - rpcSub := notifier.CreateSubscription() - - go func() { - headers := make(chan *types.Header) - headersSub := api.events.SubscribeNewHeads(headers) - - for { - select { - case h := <-headers: - _ = notifier.Notify(rpcSub.ID, h) - case <-rpcSub.Err(): - headersSub.Unsubscribe() - return - case <-notifier.Closed(): - headersSub.Unsubscribe() - return - } - } - }() - - return rpcSub, nil -} - -// Logs creates a subscription that fires for all new log that match the given filter criteria. -func (api *PublicFilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subscription, error) { - notifier, supported := rpc.NotifierFromContext(ctx) - if !supported { - return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported - } - - var ( - rpcSub = notifier.CreateSubscription() - matchedLogs = make(chan []*types.Log) - ) - - logsSub, err := api.events.SubscribeLogs(ethereum.FilterQuery(crit), matchedLogs) - if err != nil { - return nil, err - } - - go func() { - - for { - select { - case logs := <-matchedLogs: - for _, log := range logs { - _ = notifier.Notify(rpcSub.ID, &log) - } - case <-rpcSub.Err(): // client send an unsubscribe request - logsSub.Unsubscribe() - return - case <-notifier.Closed(): // connection dropped - logsSub.Unsubscribe() - return - } - } - }() - - return rpcSub, nil -} - -// FilterCriteria represents a request to create a new filter. -// Same as ethereum.FilterQuery but with UnmarshalJSON() method. -type FilterCriteria ethereum.FilterQuery - -// NewFilter creates a new filter and returns the filter id. It can be -// used to retrieve logs when the state changes. This method cannot be -// used to fetch logs that are already stored in the state. -// -// Default criteria for the from and to block are "latest". -// Using "latest" as block number will return logs for mined blocks. -// Using "pending" as block number returns logs for not yet mined (pending) blocks. -// In case logs are removed (chain reorg) previously returned logs are returned -// again but with the removed property set to true. -// -// In case "fromBlock" > "toBlock" an error is returned. -// -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter -func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) { - logs := make(chan []*types.Log) - logsSub, err := api.events.SubscribeLogs(ethereum.FilterQuery(crit), logs) - if err != nil { - return rpc.ID(""), err - } - - api.filtersMu.Lock() - api.filters[logsSub.ID] = &filter{typ: LogsSubscription, crit: crit, deadline: time.NewTimer(deadline), logs: make([]*types.Log, 0), s: logsSub} - api.filtersMu.Unlock() - - go func() { - for { - select { - case l := <-logs: - api.filtersMu.Lock() - if f, found := api.filters[logsSub.ID]; found { - f.logs = append(f.logs, l...) - } - api.filtersMu.Unlock() - case <-logsSub.Err(): - api.filtersMu.Lock() - delete(api.filters, logsSub.ID) - api.filtersMu.Unlock() - return - } - } - }() - - return logsSub.ID, nil -} - -// GetLogs returns logs matching the given argument that are stored within the state. -// -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs -func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) { - var filter *Filter - if crit.BlockHash != nil { - // Block filter requested, construct a single-shot filter - filter = NewBlockFilter(api.backend, api.config, *crit.BlockHash, crit.Addresses, crit.Topics) - } else { - // Convert the RPC block numbers into internal representations - begin := rpc.LatestBlockNumber.Int64() - if crit.FromBlock != nil { - begin = crit.FromBlock.Int64() - } - end := rpc.LatestBlockNumber.Int64() - if crit.ToBlock != nil { - end = crit.ToBlock.Int64() - } - // Construct the range filter - filter = NewRangeFilter(api.backend, api.config, begin, end, crit.Addresses, crit.Topics) - } - // Run the filter and return all the logs - logs, err := filter.Logs(ctx) - if err != nil { - return nil, err - } - return returnLogs(logs), err -} - -// UninstallFilter removes the filter with the given filter id. -// -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_uninstallfilter -func (api *PublicFilterAPI) UninstallFilter(id rpc.ID) bool { - api.filtersMu.Lock() - f, found := api.filters[id] - if found { - delete(api.filters, id) - } - api.filtersMu.Unlock() - if found { - f.s.Unsubscribe() - } - - return found -} - -// GetFilterLogs returns the logs for the filter with the given id. -// If the filter could not be found an empty array of logs is returned. -// -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterlogs -func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*types.Log, error) { - api.filtersMu.Lock() - f, found := api.filters[id] - api.filtersMu.Unlock() - - if !found || f.typ != LogsSubscription { - return nil, fmt.Errorf("filter not found") - } - - var filter *Filter - if f.crit.BlockHash != nil { - // Block filter requested, construct a single-shot filter - filter = NewBlockFilter(api.backend, api.config, *f.crit.BlockHash, f.crit.Addresses, f.crit.Topics) - } else { - // Convert the RPC block numbers into internal representations - begin := rpc.LatestBlockNumber.Int64() - if f.crit.FromBlock != nil { - begin = f.crit.FromBlock.Int64() - } - end := rpc.LatestBlockNumber.Int64() - if f.crit.ToBlock != nil { - end = f.crit.ToBlock.Int64() - } - // Construct the range filter - filter = NewRangeFilter(api.backend, api.config, begin, end, f.crit.Addresses, f.crit.Topics) - } - // Run the filter and return all the logs - logs, err := filter.Logs(ctx) - if err != nil { - return nil, err - } - return returnLogs(logs), nil -} - -// GetFilterChanges returns the logs for the filter with the given id since -// last time it was called. This can be used for polling. -// -// For pending transaction and block filters the result is []common.Hash. -// (pending)Log filters return []Log. -// -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterchanges -func (api *PublicFilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) { - api.filtersMu.Lock() - defer api.filtersMu.Unlock() - - if f, found := api.filters[id]; found { - if !f.deadline.Stop() { - // timer expired but filter is not yet removed in timeout loop - // receive timer value and reset timer - <-f.deadline.C - } - f.deadline.Reset(deadline) - - switch f.typ { - case PendingTransactionsSubscription, BlocksSubscription: - hashes := f.hashes - f.hashes = nil - return returnHashes(hashes), nil - case LogsSubscription: - logs := f.logs - f.logs = nil - return returnLogs(logs), nil - } - } - - return []interface{}{}, fmt.Errorf("filter not found") -} - -// returnHashes is a helper that will return an empty hash array case the given hash array is nil, -// otherwise the given hashes array is returned. -func returnHashes(hashes []common.Hash) []common.Hash { - if hashes == nil { - return []common.Hash{} - } - return hashes -} - -// returnLogs is a helper that will return an empty log array in case the given logs array is nil, -// otherwise the given logs array is returned. -func returnLogs(logs []*types.Log) []*types.Log { - if logs == nil { - return []*types.Log{} - } - return logs -} - -// UnmarshalJSON sets *args fields with given data. -func (args *FilterCriteria) UnmarshalJSON(data []byte) error { - type input struct { - BlockHash *common.Hash `json:"blockHash"` - FromBlock *rpc.BlockNumber `json:"fromBlock"` - ToBlock *rpc.BlockNumber `json:"toBlock"` - Addresses interface{} `json:"address"` - Topics []interface{} `json:"topics"` - } - - var raw input - if err := json.Unmarshal(data, &raw); err != nil { - return err - } - - if raw.BlockHash != nil { - if raw.FromBlock != nil || raw.ToBlock != nil { - // BlockHash is mutually exclusive with FromBlock/ToBlock criteria - return fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock, choose one or the other") - } - args.BlockHash = raw.BlockHash - } else { - if raw.FromBlock != nil { - args.FromBlock = big.NewInt(raw.FromBlock.Int64()) - } - - if raw.ToBlock != nil { - args.ToBlock = big.NewInt(raw.ToBlock.Int64()) - } - } - - args.Addresses = []common.Address{} - - if raw.Addresses != nil { - // raw.Address can contain a single address or an array of addresses - switch rawAddr := raw.Addresses.(type) { - case []interface{}: - for i, addr := range rawAddr { - if strAddr, ok := addr.(string); ok { - addr, err := decodeAddress(strAddr) - if err != nil { - return fmt.Errorf("invalid address at index %d: %v", i, err) - } - args.Addresses = append(args.Addresses, addr) - } else { - return fmt.Errorf("non-string address at index %d", i) - } - } - case string: - addr, err := decodeAddress(rawAddr) - if err != nil { - return fmt.Errorf("invalid address: %v", err) - } - args.Addresses = []common.Address{addr} - default: - return errors.New("invalid addresses in query") - } - } - - // topics is an array consisting of strings and/or arrays of strings. - // JSON null values are converted to common.Hash{} and ignored by the filter manager. - if len(raw.Topics) > 0 { - args.Topics = make([][]common.Hash, len(raw.Topics)) - for i, t := range raw.Topics { - switch topic := t.(type) { - case nil: - // ignore topic when matching logs - - case string: - // match specific topic - top, err := decodeTopic(topic) - if err != nil { - return err - } - args.Topics[i] = []common.Hash{top} - - case []interface{}: - // or case e.g. [null, "topic0", "topic1"] - for _, rawTopic := range topic { - if rawTopic == nil { - // null component, match all - args.Topics[i] = nil - break - } - if topic, ok := rawTopic.(string); ok { - parsed, err := decodeTopic(topic) - if err != nil { - return err - } - args.Topics[i] = append(args.Topics[i], parsed) - } else { - return fmt.Errorf("invalid topic(s)") - } - } - default: - return fmt.Errorf("invalid topic(s)") - } - } - } - - return nil -} - -func decodeAddress(s string) (common.Address, error) { - b, err := hexutil.Decode(s) - if err == nil && len(b) != common.AddressLength { - err = fmt.Errorf("hex has invalid length %d after decoding; expected %d for address", len(b), common.AddressLength) - } - return common.BytesToAddress(b), err -} - -func decodeTopic(s string) (common.Hash, error) { - b, err := hexutil.Decode(s) - if err == nil && len(b) != common.HashLength { - err = fmt.Errorf("hex has invalid length %d after decoding; expected %d for topic", len(b), common.HashLength) - } - return common.BytesToHash(b), err -} diff --git a/evm/go-x1/gossip/filters/api_test.go b/evm/go-x1/gossip/filters/api_test.go deleted file mode 100644 index 02229a7..0000000 --- a/evm/go-x1/gossip/filters/api_test.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package filters - -import ( - "encoding/json" - "fmt" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rpc" -) - -func TestUnmarshalJSONNewFilterArgs(t *testing.T) { - var ( - fromBlock rpc.BlockNumber = 0x123435 - toBlock rpc.BlockNumber = 0xabcdef - address0 = common.HexToAddress("70c87d191324e6712a591f304b4eedef6ad9bb9d") - address1 = common.HexToAddress("9b2055d370f73ec7d8a03e965129118dc8f5bf83") - topic0 = common.HexToHash("3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1ca") - topic1 = common.HexToHash("9084a792d2f8b16a62b882fd56f7860c07bf5fa91dd8a2ae7e809e5180fef0b3") - topic2 = common.HexToHash("6ccae1c4af4152f460ff510e573399795dfab5dcf1fa60d1f33ac8fdc1e480ce") - ) - - // default values - var test0 FilterCriteria - if err := json.Unmarshal([]byte("{}"), &test0); err != nil { - t.Fatal(err) - } - if test0.FromBlock != nil { - t.Fatalf("expected nil, got %d", test0.FromBlock) - } - if test0.ToBlock != nil { - t.Fatalf("expected nil, got %d", test0.ToBlock) - } - if len(test0.Addresses) != 0 { - t.Fatalf("expected 0 addresses, got %d", len(test0.Addresses)) - } - if len(test0.Topics) != 0 { - t.Fatalf("expected 0 topics, got %d topics", len(test0.Topics)) - } - - // from, to block number - var test1 FilterCriteria - vector := fmt.Sprintf(`{"fromBlock":"0x%x","toBlock":"0x%x"}`, fromBlock, toBlock) - if err := json.Unmarshal([]byte(vector), &test1); err != nil { - t.Fatal(err) - } - if test1.FromBlock.Int64() != fromBlock.Int64() { - t.Fatalf("expected FromBlock %d, got %d", fromBlock, test1.FromBlock) - } - if test1.ToBlock.Int64() != toBlock.Int64() { - t.Fatalf("expected ToBlock %d, got %d", toBlock, test1.ToBlock) - } - - // single address - var test2 FilterCriteria - vector = fmt.Sprintf(`{"address": "%s"}`, address0.Hex()) - if err := json.Unmarshal([]byte(vector), &test2); err != nil { - t.Fatal(err) - } - if len(test2.Addresses) != 1 { - t.Fatalf("expected 1 address, got %d address(es)", len(test2.Addresses)) - } - if test2.Addresses[0] != address0 { - t.Fatalf("expected address %x, got %x", address0, test2.Addresses[0]) - } - - // multiple address - var test3 FilterCriteria - vector = fmt.Sprintf(`{"address": ["%s", "%s"]}`, address0.Hex(), address1.Hex()) - if err := json.Unmarshal([]byte(vector), &test3); err != nil { - t.Fatal(err) - } - if len(test3.Addresses) != 2 { - t.Fatalf("expected 2 addresses, got %d address(es)", len(test3.Addresses)) - } - if test3.Addresses[0] != address0 { - t.Fatalf("expected address %x, got %x", address0, test3.Addresses[0]) - } - if test3.Addresses[1] != address1 { - t.Fatalf("expected address %x, got %x", address1, test3.Addresses[1]) - } - - // single topic - var test4 FilterCriteria - vector = fmt.Sprintf(`{"topics": ["%s"]}`, topic0.Hex()) - if err := json.Unmarshal([]byte(vector), &test4); err != nil { - t.Fatal(err) - } - if len(test4.Topics) != 1 { - t.Fatalf("expected 1 topic, got %d", len(test4.Topics)) - } - if len(test4.Topics[0]) != 1 { - t.Fatalf("expected len(topics[0]) to be 1, got %d", len(test4.Topics[0])) - } - if test4.Topics[0][0] != topic0 { - t.Fatalf("got %x, expected %x", test4.Topics[0][0], topic0) - } - - // test multiple "AND" topics - var test5 FilterCriteria - vector = fmt.Sprintf(`{"topics": ["%s", "%s"]}`, topic0.Hex(), topic1.Hex()) - if err := json.Unmarshal([]byte(vector), &test5); err != nil { - t.Fatal(err) - } - if len(test5.Topics) != 2 { - t.Fatalf("expected 2 topics, got %d", len(test5.Topics)) - } - if len(test5.Topics[0]) != 1 { - t.Fatalf("expected 1 topic, got %d", len(test5.Topics[0])) - } - if test5.Topics[0][0] != topic0 { - t.Fatalf("got %x, expected %x", test5.Topics[0][0], topic0) - } - if len(test5.Topics[1]) != 1 { - t.Fatalf("expected 1 topic, got %d", len(test5.Topics[1])) - } - if test5.Topics[1][0] != topic1 { - t.Fatalf("got %x, expected %x", test5.Topics[1][0], topic1) - } - - // test optional topic - var test6 FilterCriteria - vector = fmt.Sprintf(`{"topics": ["%s", null, "%s"]}`, topic0.Hex(), topic2.Hex()) - if err := json.Unmarshal([]byte(vector), &test6); err != nil { - t.Fatal(err) - } - if len(test6.Topics) != 3 { - t.Fatalf("expected 3 topics, got %d", len(test6.Topics)) - } - if len(test6.Topics[0]) != 1 { - t.Fatalf("expected 1 topic, got %d", len(test6.Topics[0])) - } - if test6.Topics[0][0] != topic0 { - t.Fatalf("got %x, expected %x", test6.Topics[0][0], topic0) - } - if len(test6.Topics[1]) != 0 { - t.Fatalf("expected 0 topic, got %d", len(test6.Topics[1])) - } - if len(test6.Topics[2]) != 1 { - t.Fatalf("expected 1 topic, got %d", len(test6.Topics[2])) - } - if test6.Topics[2][0] != topic2 { - t.Fatalf("got %x, expected %x", test6.Topics[2][0], topic2) - } - - // test OR topics - var test7 FilterCriteria - vector = fmt.Sprintf(`{"topics": [["%s", "%s"], null, ["%s", null]]}`, topic0.Hex(), topic1.Hex(), topic2.Hex()) - if err := json.Unmarshal([]byte(vector), &test7); err != nil { - t.Fatal(err) - } - if len(test7.Topics) != 3 { - t.Fatalf("expected 3 topics, got %d topics", len(test7.Topics)) - } - if len(test7.Topics[0]) != 2 { - t.Fatalf("expected 2 topics, got %d topics", len(test7.Topics[0])) - } - if test7.Topics[0][0] != topic0 || test7.Topics[0][1] != topic1 { - t.Fatalf("invalid topics expected [%x,%x], got [%x,%x]", - topic0, topic1, test7.Topics[0][0], test7.Topics[0][1], - ) - } - if len(test7.Topics[1]) != 0 { - t.Fatalf("expected 0 topic, got %d topics", len(test7.Topics[1])) - } - if len(test7.Topics[2]) != 0 { - t.Fatalf("expected 0 topics, got %d topics", len(test7.Topics[2])) - } -} diff --git a/evm/go-x1/gossip/filters/filter.go b/evm/go-x1/gossip/filters/filter.go deleted file mode 100644 index 45bdda5..0000000 --- a/evm/go-x1/gossip/filters/filter.go +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package filters - -import ( - "context" - "errors" - "fmt" - "math/big" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" - notify "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rpc" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/topicsdb" -) - -type Backend interface { - ChainDb() ethdb.Database - HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*evmcore.EvmHeader, error) - HeaderByHash(ctx context.Context, blockHash common.Hash) (*evmcore.EvmHeader, error) - GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) - GetReceiptsByNumber(ctx context.Context, number rpc.BlockNumber) (types.Receipts, error) - GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) - GetTxPosition(txid common.Hash) *evmstore.TxPosition - - SubscribeNewBlockNotify(ch chan<- evmcore.ChainHeadNotify) notify.Subscription - SubscribeNewTxsNotify(chan<- evmcore.NewTxsNotify) notify.Subscription - SubscribeLogsNotify(ch chan<- []*types.Log) notify.Subscription - - EvmLogIndex() topicsdb.Index - - CalcBlockExtApi() bool -} - -// Filter can be used to retrieve and filter logs. -type Filter struct { - backend Backend - config Config - - db ethdb.Database - addresses []common.Address - topics [][]common.Hash - - block common.Hash // Block hash if filtering a single block - begin, end int64 // Range interval if filtering multiple blocks -} - -// NewRangeFilter creates a new filter which inspects the blocks to -// figure out whether a particular block is interesting or not. -func NewRangeFilter(backend Backend, cfg Config, begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter { - // Create a generic filter and convert it into a range filter - filter := newFilter(backend, cfg, addresses, topics) - - filter.begin = begin - filter.end = end - - return filter -} - -// NewBlockFilter creates a new filter which directly inspects the contents of -// a block to figure out whether it is interesting or not. -func NewBlockFilter(backend Backend, cfg Config, block common.Hash, addresses []common.Address, topics [][]common.Hash) *Filter { - // Create a generic filter and convert it into a block filter - filter := newFilter(backend, cfg, addresses, topics) - - filter.block = block - - return filter -} - -// newFilter creates a generic filter that can either filter based on a block hash, -// or based on range queries. The search criteria needs to be explicitly set. -func newFilter(backend Backend, cfg Config, addresses []common.Address, topics [][]common.Hash) *Filter { - return &Filter{ - backend: backend, - config: cfg, - addresses: addresses, - topics: topics, - db: backend.ChainDb(), - } -} - -// Logs searches the blockchain for matching log entries, returning all from the -// first block that contains matches, updating the start of the filter accordingly. -func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { - // If we're doing singleton block filtering, execute and return - if f.block != common.Hash(hash.Zero) { - header, err := f.backend.HeaderByHash(ctx, f.block) - if err != nil { - return nil, err - } - if header == nil { - return nil, errors.New("unknown block") - } - return f.blockLogs(ctx, header.Hash) - } - // Figure out the limits of the filter range - header, _ := f.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber) - if header == nil { - return nil, nil - } - head := idx.Block(header.Number.Uint64()) - - begin := idx.Block(f.begin) - if f.begin < 0 { - begin = head - } - end := idx.Block(f.end) - if f.end < 0 { - end = head - } - if begin > end { - return []*types.Log{}, nil - } - - if isEmpty(f.topics) && len(f.addresses) == 0 { - return f.unindexedLogs(ctx, begin, end) - } else { - return f.indexedLogs(ctx, begin, end) - } -} - -// indexedLogs returns the logs matching the filter criteria based on topics index. -func (f *Filter) indexedLogs(ctx context.Context, begin, end idx.Block) ([]*types.Log, error) { - if end-begin > f.config.IndexedLogsBlockRangeLimit { - return nil, fmt.Errorf("too wide blocks range, the limit is %d", f.config.IndexedLogsBlockRangeLimit) - } - - addresses := make([]common.Hash, len(f.addresses)) - for i, addr := range f.addresses { - addresses[i] = addr.Hash() - } - - pattern := make([][]common.Hash, 1, len(f.topics)+1) - pattern[0] = addresses - pattern = append(pattern, f.topics...) - - logs, err := f.backend.EvmLogIndex().FindInBlocks(ctx, begin, end, pattern) - if err != nil { - return nil, err - } - - for _, l := range logs { - pos := f.backend.GetTxPosition(l.TxHash) - if pos != nil { - l.TxIndex = uint(pos.BlockOffset) - } else { - log.Warn("tx index empty", "hash", l.TxHash) - } - } - - return logs, nil -} - -// indexedLogs returns the logs matching the filter criteria based on raw block -// iteration. -func (f *Filter) unindexedLogs(ctx context.Context, begin, end idx.Block) (logs []*types.Log, err error) { - if end-begin > f.config.UnindexedLogsBlockRangeLimit { - return nil, fmt.Errorf("too wide blocks range, the limit is %d", f.config.UnindexedLogsBlockRangeLimit) - } - - var ( - header *evmcore.EvmHeader - found []*types.Log - ) - for n := begin; n <= end; n++ { - err = ctx.Err() - if err != nil { - return - } - - header, err = f.backend.HeaderByNumber(ctx, rpc.BlockNumber(n)) - if header == nil || err != nil { - return - } - found, err = f.blockLogs(ctx, header.Hash) - if err != nil { - return - } - logs = append(logs, found...) - } - return -} - -// blockLogs returns the logs matching the filter criteria within a single block. -func (f *Filter) blockLogs(ctx context.Context, header common.Hash) ([]*types.Log, error) { - // Get the logs of the block - logsList, err := f.backend.GetLogs(ctx, header) - if err != nil { - return nil, err - } - - var unfiltered []*types.Log - for _, logs := range logsList { - unfiltered = append(unfiltered, logs...) - } - - logs := filterLogs(unfiltered, nil, nil, f.addresses, f.topics) - if len(logs) > 0 { - // We have matching logs, check if we need to resolve full logs via the light client - if logs[0].TxHash == common.Hash(hash.Zero) { - receipts, err := f.backend.GetReceipts(ctx, header) - if err != nil { - return nil, err - } - unfiltered = unfiltered[:0] - for _, receipt := range receipts { - unfiltered = append(unfiltered, receipt.Logs...) - } - logs = filterLogs(unfiltered, nil, nil, f.addresses, f.topics) - } - return logs, nil - } - return nil, nil -} - -func includes(addresses []common.Address, a common.Address) bool { - for _, addr := range addresses { - if addr == a { - return true - } - } - - return false -} - -// filterLogs creates a slice of logs matching the given criteria. -func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log { - var ret []*types.Log -Logs: - for _, log := range logs { - if fromBlock != nil && fromBlock.Int64() >= 0 && fromBlock.Uint64() > log.BlockNumber { - continue - } - if toBlock != nil && toBlock.Int64() >= 0 && toBlock.Uint64() < log.BlockNumber { - continue - } - - if len(addresses) > 0 && !includes(addresses, log.Address) { - continue - } - // If the to filtered topics is greater than the amount of topics in logs, skip. - if len(topics) > len(log.Topics) { - continue Logs - } - for i, sub := range topics { - match := len(sub) == 0 // empty rule set == wildcard - for _, topic := range sub { - if log.Topics[i] == topic { - match = true - break - } - } - if !match { - continue Logs - } - } - ret = append(ret, log) - } - return ret -} - -func isEmpty(topics [][]common.Hash) bool { - for _, tt := range topics { - if len(tt) > 0 { - return false - } - } - return true -} diff --git a/evm/go-x1/gossip/filters/filter_system.go b/evm/go-x1/gossip/filters/filter_system.go deleted file mode 100644 index 879f0f0..0000000 --- a/evm/go-x1/gossip/filters/filter_system.go +++ /dev/null @@ -1,398 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package filters implements an ethereum filtering system for block, -// transactions and log events. -package filters - -import ( - "context" - "errors" - "fmt" - "sync" - "time" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - notify "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/trie" - - "github.com/Fantom-foundation/go-opera/evmcore" -) - -// Type determines the kind of filter and is used to put the filter in to -// the correct bucket when added. -type Type byte - -const ( - // UnknownSubscription indicates an unknown subscription type - UnknownSubscription Type = iota - // LogsSubscription queries for new or removed (chain reorg) logs - LogsSubscription - // PendingLogsSubscription queries for logs in pending blocks - PendingLogsSubscription - // MinedAndPendingLogsSubscription queries for logs in mined and pending blocks. - MinedAndPendingLogsSubscription - // PendingTransactionsSubscription queries tx hashes for pending - // transactions entering the pending state - PendingTransactionsSubscription - // BlocksSubscription queries hashes for blocks that are imported - BlocksSubscription - // LastIndexSubscription keeps track of the last index - LastIndexSubscription -) - -const ( - - // txChanSize is the size of channel listening to NewTxsEvent. - // The number is referenced from the size of tx pool. - txChanSize = 4096 - // logsChanSize is the size of channel listening to LogsEvent. - logsChanSize = 10 - // blocksChanSize is the size of channel listening to BlocksEvent. - blocksChanSize = 10 -) - -var ( - ErrInvalidSubscriptionID = errors.New("invalid id") -) - -type subscription struct { - id rpc.ID - typ Type - created time.Time - logsCrit ethereum.FilterQuery - logs chan []*types.Log - hashes chan []common.Hash - headers chan *types.Header - installed chan struct{} // closed when the filter is installed - err chan error // closed when the filter is uninstalled -} - -// EventSystem creates subscriptions, processes events and broadcasts them to the -// subscription which match the subscription criteria. -type EventSystem struct { - backend Backend - - // Subscriptions - txsSub notify.Subscription // Subscription for new transaction notify - logsSub notify.Subscription // Subscription for new log notify - blocksSub notify.Subscription // Subscription for new chain notify - - // Channels - install chan *subscription // install filter for event notification - uninstall chan *subscription // remove filter for event notification - txsCh chan evmcore.NewTxsNotify // Channel to receive new transactions notify - logsCh chan []*types.Log // Channel to receive new log notify - blocksCh chan evmcore.ChainHeadNotify // Channel to receive new chain notify -} - -// NewEventSystem creates a new manager that listens for event on the given chans, -// parses and filters them. It uses the all map to retrieve filter changes. The -// work loop holds its own index that is used to forward events to filters. -// -// The returned manager has a loop that needs to be stopped with the Stop function. -func NewEventSystem(backend Backend) *EventSystem { - m := &EventSystem{ - backend: backend, - install: make(chan *subscription), - uninstall: make(chan *subscription), - blocksCh: make(chan evmcore.ChainHeadNotify, blocksChanSize), - txsCh: make(chan evmcore.NewTxsNotify, txChanSize), - logsCh: make(chan []*types.Log, logsChanSize), - } - - // Subscribe events - m.blocksSub = m.backend.SubscribeNewBlockNotify(m.blocksCh) - m.txsSub = m.backend.SubscribeNewTxsNotify(m.txsCh) - m.logsSub = m.backend.SubscribeLogsNotify(m.logsCh) - - // Make sure none of the subscriptions are empty - if m.txsSub == nil || m.logsSub == nil || m.blocksSub == nil { - log.Crit("Subscribe for event system failed") - } - - go m.eventLoop() - return m -} - -// Subscription is created when the client registers itself for a particular event. -type Subscription struct { - ID rpc.ID - f *subscription - es *EventSystem - unsubOnce sync.Once -} - -// Err returns a channel that is closed when unsubscribed. -func (sub *Subscription) Err() <-chan error { - return sub.f.err -} - -// Unsubscribe uninstalls the subscription from the event broadcast loop. -func (sub *Subscription) Unsubscribe() { - sub.unsubOnce.Do(func() { - uninstallLoop: - for { - // write uninstall request and consume logs/hashes. This prevents - // the eventLoop broadcast method to deadlock when writing to the - // filter event channel while the subscription loop is waiting for - // this method to return (and thus not reading these events). - select { - case sub.es.uninstall <- sub.f: - break uninstallLoop - case <-sub.f.logs: - case <-sub.f.hashes: - case <-sub.f.headers: - } - } - - // wait for filter to be uninstalled in work loop before returning - // this ensures that the manager won't use the event channel which - // will probably be closed by the client asap after this method returns. - <-sub.Err() - }) -} - -// subscribe installs the subscription in the event broadcast loop. -func (es *EventSystem) subscribe(sub *subscription) *Subscription { - es.install <- sub - <-sub.installed - return &Subscription{ID: sub.id, f: sub, es: es} -} - -// SubscribeLogs creates a subscription that will write all logs matching the -// given criteria to the given logs channel. Default value for the from and to -// block is "latest". If the fromBlock > toBlock an error is returned. -func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) (*Subscription, error) { - var from, to rpc.BlockNumber - if crit.FromBlock == nil { - from = rpc.LatestBlockNumber - } else { - from = rpc.BlockNumber(crit.FromBlock.Int64()) - } - if crit.ToBlock == nil { - to = rpc.LatestBlockNumber - } else { - to = rpc.BlockNumber(crit.ToBlock.Int64()) - } - - // only interested in pending logs - if from == rpc.PendingBlockNumber && to == rpc.PendingBlockNumber { - return es.subscribePendingLogs(crit, logs), nil - } - // only interested in new mined logs - if from == rpc.LatestBlockNumber && to == rpc.LatestBlockNumber { - return es.subscribeLogs(crit, logs), nil - } - // only interested in mined logs within a specific block range - if from >= 0 && to >= 0 && to >= from { - return es.subscribeLogs(crit, logs), nil - } - // interested in mined logs from a specific block number, new logs and pending logs - if from >= rpc.LatestBlockNumber && to == rpc.PendingBlockNumber { - return es.subscribeMinedPendingLogs(crit, logs), nil - } - // interested in logs from a specific block number to new mined blocks - if from >= 0 && to == rpc.LatestBlockNumber { - return es.subscribeLogs(crit, logs), nil - } - return nil, fmt.Errorf("invalid from and to block combination: from > to") -} - -// subscribeMinedPendingLogs creates a subscription that returned mined and -// pending logs that match the given criteria. -func (es *EventSystem) subscribeMinedPendingLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { - sub := &subscription{ - id: rpc.NewID(), - typ: MinedAndPendingLogsSubscription, - logsCrit: crit, - created: time.Now(), - logs: logs, - hashes: make(chan []common.Hash), - headers: make(chan *types.Header), - installed: make(chan struct{}), - err: make(chan error), - } - return es.subscribe(sub) -} - -// subscribeLogs creates a subscription that will write all logs matching the -// given criteria to the given logs channel. -func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { - sub := &subscription{ - id: rpc.NewID(), - typ: LogsSubscription, - logsCrit: crit, - created: time.Now(), - logs: logs, - hashes: make(chan []common.Hash), - headers: make(chan *types.Header), - installed: make(chan struct{}), - err: make(chan error), - } - return es.subscribe(sub) -} - -// subscribePendingLogs creates a subscription that writes transaction hashes for -// transactions that enter the transaction pool. -func (es *EventSystem) subscribePendingLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { - sub := &subscription{ - id: rpc.NewID(), - typ: PendingLogsSubscription, - logsCrit: crit, - created: time.Now(), - logs: logs, - hashes: make(chan []common.Hash), - headers: make(chan *types.Header), - installed: make(chan struct{}), - err: make(chan error), - } - return es.subscribe(sub) -} - -// SubscribeNewHeads creates a subscription that writes the header of a block that is -// imported in the chain. -func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscription { - sub := &subscription{ - id: rpc.NewID(), - typ: BlocksSubscription, - created: time.Now(), - logs: make(chan []*types.Log), - hashes: make(chan []common.Hash), - headers: headers, - installed: make(chan struct{}), - err: make(chan error), - } - return es.subscribe(sub) -} - -// SubscribePendingTxs creates a subscription that writes transaction hashes for -// transactions that enter the transaction pool. -func (es *EventSystem) SubscribePendingTxs(hashes chan []common.Hash) *Subscription { - sub := &subscription{ - id: rpc.NewID(), - typ: PendingTransactionsSubscription, - created: time.Now(), - logs: make(chan []*types.Log), - hashes: hashes, - headers: make(chan *types.Header), - installed: make(chan struct{}), - err: make(chan error), - } - return es.subscribe(sub) -} - -type filterIndex map[Type]map[rpc.ID]*subscription - -// broadcast event to filters that match criteria. -func (es *EventSystem) broadcast(filters filterIndex, ev interface{}) { - if ev == nil { - return - } - - switch e := ev.(type) { - case []*types.Log: - if len(e) > 0 { - for _, f := range filters[LogsSubscription] { - if matchedLogs := filterLogs(e, f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics); len(matchedLogs) > 0 { - f.logs <- matchedLogs - } - } - } - case evmcore.NewTxsNotify: - hashes := make([]common.Hash, 0, len(e.Txs)) - for _, tx := range e.Txs { - hashes = append(hashes, tx.Hash()) - } - for _, f := range filters[PendingTransactionsSubscription] { - f.hashes <- hashes - } - case evmcore.ChainHeadNotify: - h := e.Block.EthHeader() - h.GasLimit = 0xffffffffffff // don't use too much bits here to avoid parsing issues - es.calculateExtBlockApi(h) - for _, f := range filters[BlocksSubscription] { - f.headers <- h - } - } -} - -// calculateExtBlockApi doubles ethapi/PublicBlockChainAPI.calculateExtBlockApi() functionality. -// TODO: common code. -func (es *EventSystem) calculateExtBlockApi(h *types.Header) { - blkNumber := rpc.BlockNumber(h.Number.Int64()) - if !es.backend.CalcBlockExtApi() || blkNumber == rpc.EarliestBlockNumber { - return - } - - receipts, err := es.backend.GetReceiptsByNumber(context.Background(), blkNumber) - if err != nil { - return - } - if receipts.Len() != 0 { - h.ReceiptHash = types.DeriveSha(receipts, trie.NewStackTrie(nil)) - h.Bloom = types.CreateBloom(receipts) - } else { - h.ReceiptHash = types.EmptyRootHash - } -} - -// eventLoop (un)installs filters and processes mux events. -func (es *EventSystem) eventLoop() { - // Ensure all subscriptions get cleaned up - defer func() { - es.blocksSub.Unsubscribe() - es.txsSub.Unsubscribe() - es.logsSub.Unsubscribe() - }() - - index := make(filterIndex) - for i := UnknownSubscription; i < LastIndexSubscription; i++ { - index[i] = make(map[rpc.ID]*subscription) - } - - for { - select { - // Handle subscribed events - case ev := <-es.txsCh: - es.broadcast(index, ev) - case ev := <-es.logsCh: - es.broadcast(index, ev) - case ev := <-es.blocksCh: - es.broadcast(index, ev) - - case f := <-es.install: - index[f.typ][f.id] = f - close(f.installed) - - case f := <-es.uninstall: - delete(index[f.typ], f.id) - close(f.err) - - // System stopped - case <-es.txsSub.Err(): - return - case <-es.logsSub.Err(): - return - case <-es.blocksSub.Err(): - return - } - } -} diff --git a/evm/go-x1/gossip/filters/filter_system_test.go b/evm/go-x1/gossip/filters/filter_system_test.go deleted file mode 100644 index c551aa6..0000000 --- a/evm/go-x1/gossip/filters/filter_system_test.go +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package filters - -import ( - "context" - "math/big" - "reflect" - "testing" - "time" - - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" - notify "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rpc" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/topicsdb" -) - -type testBackend struct { - db ethdb.Database - logIndex topicsdb.Index - blocksFeed *notify.Feed - txsFeed *notify.Feed - logsFeed *notify.Feed -} - -func newTestBackend() *testBackend { - return &testBackend{ - db: rawdb.NewMemoryDatabase(), - logIndex: topicsdb.NewWithThreadPool(memorydb.NewProducer("")), - blocksFeed: new(notify.Feed), - txsFeed: new(notify.Feed), - logsFeed: new(notify.Feed), - } -} - -func (b *testBackend) ChainDb() ethdb.Database { - return b.db -} - -func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*evmcore.EvmHeader, error) { - var ( - hash common.Hash - num uint64 - ) - if blockNr == rpc.LatestBlockNumber { - hash = rawdb.ReadHeadBlockHash(b.db) - number := rawdb.ReadHeaderNumber(b.db, hash) - if number == nil { - return nil, nil - } - num = *number - } else { - num = uint64(blockNr) - hash = rawdb.ReadCanonicalHash(b.db, num) - } - - h := rawdb.ReadHeader(b.db, hash, num) - eh := evmcore.ConvertFromEthHeader(h) - eh.Hash = h.Hash() - return eh, nil -} - -func (b *testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*evmcore.EvmHeader, error) { - number := rawdb.ReadHeaderNumber(b.db, hash) - if number == nil { - return nil, nil - } - - h := rawdb.ReadHeader(b.db, hash, *number) - eh := evmcore.ConvertFromEthHeader(h) - eh.Hash = h.Hash() - return eh, nil -} - -func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { - if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil { - return rawdb.ReadReceipts(b.db, hash, *number, params.TestChainConfig), nil - } - return nil, nil -} - -func (b *testBackend) GetReceiptsByNumber(ctx context.Context, number rpc.BlockNumber) (types.Receipts, error) { - return rawdb.ReadReceipts(b.db, common.Hash{}, uint64(number), params.TestChainConfig), nil -} - -func (b *testBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - number := rawdb.ReadHeaderNumber(b.db, hash) - if number == nil { - return nil, nil - } - - receipts := rawdb.ReadReceipts(b.db, hash, *number, params.TestChainConfig) - logs := make([][]*types.Log, len(receipts)) - for i, receipt := range receipts { - logs[i] = receipt.Logs - } - - return logs, nil -} - -func (b *testBackend) SubscribeNewTxsNotify(ch chan<- evmcore.NewTxsNotify) notify.Subscription { - return b.txsFeed.Subscribe(ch) -} - -func (b *testBackend) SubscribeLogsNotify(ch chan<- []*types.Log) notify.Subscription { - return b.logsFeed.Subscribe(ch) -} - -func (b *testBackend) SubscribeNewBlockNotify(ch chan<- evmcore.ChainHeadNotify) notify.Subscription { - return b.blocksFeed.Subscribe(ch) -} - -func (b *testBackend) EvmLogIndex() topicsdb.Index { - return b.logIndex -} - -func (b *testBackend) MustPushLogs(recs ...*types.Log) { - err := b.logIndex.Push(recs...) - if err != nil { - panic(err) - } -} - -func (b *testBackend) GetTxPosition(txid common.Hash) *evmstore.TxPosition { - return nil -} - -func (b *testBackend) CalcBlockExtApi() bool { - return true -} - -// TestBlockSubscription tests if a block subscription returns block hashes for posted chain notify. -// It creates multiple subscriptions: -// - one at the start and should receive all posted chain events and a second (blockHashes) -// - one that is created after a cutoff moment and uninstalled after a second cutoff moment (blockHashes[cutoff1:cutoff2]) -// - one that is created after the second cutoff moment (blockHashes[cutoff2:]) -func TestBlockSubscription(t *testing.T) { - t.Parallel() - - var ( - backend = newTestBackend() - api = NewPublicFilterAPI(backend, testConfig()) - - statedb, _ = state.New(common.Hash{}, state.NewDatabase(backend.db), nil) - genesis = evmcore.MustApplyFakeGenesis(statedb, evmcore.FakeGenesisTime, map[common.Address]*big.Int{}) - chain, _, _ = evmcore.GenerateChain( - params.TestChainConfig, genesis, backend.db, 10, nil) - chainEvents = []evmcore.ChainHeadNotify{} - ) - - for _, blk := range chain { - chainEvents = append(chainEvents, evmcore.ChainHeadNotify{ - Block: &evmcore.EvmBlock{ - EvmHeader: blk.EvmHeader, - Transactions: blk.Transactions, - }, - }) - } - - chan0 := make(chan *types.Header) - sub0 := api.events.SubscribeNewHeads(chan0) - chan1 := make(chan *types.Header) - sub1 := api.events.SubscribeNewHeads(chan1) - - go func() { // simulate client - i1, i2 := 0, 0 - for i1 != len(chainEvents) || i2 != len(chainEvents) { - select { - case header := <-chan0: - got := common.BytesToHash(header.Extra) - if chainEvents[i1].Block.Hash != got { - t.Errorf("sub0 received invalid hash on index %d, want %x, got %x", i1, chainEvents[i1].Block.Hash, got) - } - i1++ - case header := <-chan1: - got := common.BytesToHash(header.Extra) - if chainEvents[i2].Block.Hash != got { - t.Errorf("sub1 received invalid hash on index %d, want %x, got %x", i2, chainEvents[i2].Block.Hash, got) - } - i2++ - } - } - - sub0.Unsubscribe() - sub1.Unsubscribe() - }() - - time.Sleep(1 * time.Second) - for _, e := range chainEvents { - backend.blocksFeed.Send(e) - } - - <-sub0.Err() - <-sub1.Err() -} - -// TestPendingTxFilter tests whether pending tx filters retrieve all pending transactions that are posted to the event mux. -func TestPendingTxFilter(t *testing.T) { - t.Parallel() - - var ( - backend = newTestBackend() - api = NewPublicFilterAPI(backend, testConfig()) - - transactions = []*types.Transaction{ - types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), - types.NewTransaction(1, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), - types.NewTransaction(2, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), - types.NewTransaction(3, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), - types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), - } - - hashes []common.Hash - ) - - fid0 := api.NewPendingTransactionFilter() - - time.Sleep(1 * time.Second) - backend.txsFeed.Send(evmcore.NewTxsNotify{Txs: transactions}) - - timeout := time.Now().Add(1 * time.Second) - for { - results, err := api.GetFilterChanges(fid0) - if err != nil { - t.Fatalf("Unable to retrieve logs: %v", err) - } - - h := results.([]common.Hash) - hashes = append(hashes, h...) - if len(hashes) >= len(transactions) { - break - } - // check timeout - if time.Now().After(timeout) { - break - } - - time.Sleep(100 * time.Millisecond) - } - - if len(hashes) != len(transactions) { - t.Errorf("invalid number of transactions, want %d transactions(s), got %d", len(transactions), len(hashes)) - return - } - for i := range hashes { - if hashes[i] != transactions[i].Hash() { - t.Errorf("hashes[%d] invalid, want %x, got %x", i, transactions[i].Hash(), hashes[i]) - } - } -} - -// TestLogFilterCreation test whether a given filter criteria makes sense. -// If not it must return an error. -func TestLogFilterCreation(t *testing.T) { - var ( - backend = newTestBackend() - api = NewPublicFilterAPI(backend, testConfig()) - - testCases = []struct { - crit FilterCriteria - success bool - }{ - // defaults - {FilterCriteria{}, true}, - // valid block number range - {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2)}, true}, - // "mined" block range to pending - {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, true}, - // new mined and pending blocks - {FilterCriteria{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, true}, - // from block "higher" than to block - {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(1)}, false}, - // from block "higher" than to block - {FilterCriteria{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(100)}, false}, - // from block "higher" than to block - {FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, false}, - // from block "higher" than to block - {FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, false}, - } - ) - - for i, test := range testCases { - _, err := api.NewFilter(test.crit) - if test.success && err != nil { - t.Errorf("expected filter creation for case %d to success, got %v", i, err) - } - if !test.success && err == nil { - t.Errorf("expected testcase %d to fail with an error", i) - } - } -} - -// TestInvalidLogFilterCreation tests whether invalid filter log criteria results in an error -// when the filter is created. -func TestInvalidLogFilterCreation(t *testing.T) { - t.Parallel() - - var ( - backend = newTestBackend() - api = NewPublicFilterAPI(backend, testConfig()) - ) - - // different situations where log filter creation should fail. - // Reason: fromBlock > toBlock - testCases := []FilterCriteria{ - 0: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, - 1: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, - 2: {FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(100)}, - } - - for i, test := range testCases { - if _, err := api.NewFilter(test); err == nil { - t.Errorf("Expected NewFilter for case #%d to fail", i) - } - } -} - -func TestInvalidGetLogsRequest(t *testing.T) { - var ( - backend = newTestBackend() - api = NewPublicFilterAPI(backend, testConfig()) - blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") - ) - - // Reason: Cannot specify both BlockHash and FromBlock/ToBlock) - testCases := []FilterCriteria{ - 0: {BlockHash: &blockHash, FromBlock: big.NewInt(100)}, - 1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)}, - 2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, - } - - for i, test := range testCases { - if _, err := api.GetLogs(context.Background(), test); err == nil { - t.Errorf("Expected Logs for case #%d to fail", i) - } - } -} - -// TestLogFilter tests whether log filters match the correct logs that are posted to the event feed. -func TestLogFilter(t *testing.T) { - t.Parallel() - - var ( - backend = newTestBackend() - api = NewPublicFilterAPI(backend, testConfig()) - - firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") - secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222") - thirdAddress = common.HexToAddress("0x3333333333333333333333333333333333333333") - notUsedAddress = common.HexToAddress("0x9999999999999999999999999999999999999999") - firstTopic = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") - secondTopic = common.HexToHash("0x2222222222222222222222222222222222222222222222222222222222222222") - notUsedTopic = common.HexToHash("0x9999999999999999999999999999999999999999999999999999999999999999") - - allLogs = []*types.Log{ - {Address: firstAddr}, - {Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 1}, - {Address: secondAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 1}, - {Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 2}, - {Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 3}, - } - - testCases = []struct { - crit FilterCriteria - expected []*types.Log - id rpc.ID - }{ - // match all - 0: {FilterCriteria{}, allLogs, ""}, - // match none due to no matching addresses - 1: {FilterCriteria{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}}, []*types.Log{}, ""}, - // match logs based on addresses, ignore topics - 2: {FilterCriteria{Addresses: []common.Address{firstAddr}}, allLogs[:2], ""}, - // match none due to no matching topics (match with address) - 3: {FilterCriteria{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}}, []*types.Log{}, ""}, - // match logs based on addresses and topics - 4: {FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, allLogs[3:5], ""}, - // match logs based on multiple addresses and "or" topics - 5: {FilterCriteria{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, allLogs[2:5], ""}, - // all "mined" logs with block num >= 2 - 6: {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs[3:], ""}, - // all "mined" logs - 7: {FilterCriteria{ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs, ""}, - // all "mined" logs with 1>= block num <=2 and topic secondTopic - 8: {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2), Topics: [][]common.Hash{{secondTopic}}}, allLogs[3:4], ""}, - // match all logs due to wildcard topic - 9: {FilterCriteria{Topics: [][]common.Hash{nil}}, allLogs[1:], ""}, - } - ) - - // create all filters - for i := range testCases { - testCases[i].id, _ = api.NewFilter(testCases[i].crit) - } - - // raise events - time.Sleep(1 * time.Second) - if nsend := backend.logsFeed.Send(allLogs); nsend == 0 { - t.Fatal("Shoud have at least one subscription") - } - - for i, tt := range testCases { - var fetched []*types.Log - timeout := time.Now().Add(1 * time.Second) - for { // fetch all expected logs - results, err := api.GetFilterChanges(tt.id) - if err != nil { - t.Fatalf("Unable to fetch logs: %v", err) - } - - fetched = append(fetched, results.([]*types.Log)...) - if len(fetched) >= len(tt.expected) { - break - } - // check timeout - if time.Now().After(timeout) { - break - } - - time.Sleep(100 * time.Millisecond) - } - - if len(fetched) != len(tt.expected) { - t.Errorf("invalid number of logs for case %d, want %d log(s), got %d", i, len(tt.expected), len(fetched)) - return - } - - for l := range fetched { - if fetched[l].Removed { - t.Errorf("expected log not to be removed for log %d in case %d", l, i) - } - if !reflect.DeepEqual(fetched[l], tt.expected[l]) { - t.Errorf("invalid log on index %d for case %d", l, i) - } - } - } -} diff --git a/evm/go-x1/gossip/filters/filter_test.go b/evm/go-x1/gossip/filters/filter_test.go deleted file mode 100644 index 2a93d4e..0000000 --- a/evm/go-x1/gossip/filters/filter_test.go +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package filters - -import ( - "context" - "io/ioutil" - "math/big" - "os" - "path" - "testing" - - "github.com/Fantom-foundation/lachesis-base/kvdb/leveldb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus/ethash" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/params" - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/go-opera/topicsdb" -) - -func testConfig() Config { - return Config{ - IndexedLogsBlockRangeLimit: 1000, - UnindexedLogsBlockRangeLimit: 1000, - } -} - -func makeReceipt(addr common.Address) *types.Receipt { - receipt := types.NewReceipt(nil, false, 0) - receipt.Logs = []*types.Log{ - {Address: addr}, - } - return receipt -} - -func BenchmarkFilters(b *testing.B) { - dir, err := ioutil.TempDir("", "filtertest") - if err != nil { - b.Fatal(err) - } - defer os.RemoveAll(dir) - - backend := newTestBackend() - ldb, err := rawdb.NewLevelDBDatabase(path.Join(dir, "backend-db"), 100, 1000, "", false) - if err != nil { - b.Fatal(err) - } - backend.db = rawdb.NewTable(ldb, "a") - backend.logIndex = topicsdb.NewWithThreadPool(leveldb.NewProducer(dir, func(string) (int, int) { - return 100 * opt.MiB, 1000 - })) - defer backend.logIndex.Close() - - var ( - key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr1 = crypto.PubkeyToAddress(key1.PublicKey) - addr2 = common.BytesToAddress([]byte("jeff")) - addr3 = common.BytesToAddress([]byte("ethereum")) - addr4 = common.BytesToAddress([]byte("random addresses please")) - ) - - genesis := core.GenesisBlockForTesting(backend.db, addr1, big.NewInt(1000000)) - chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), backend.db, 100010, func(i int, gen *core.BlockGen) { - switch i { - case 2403: - receipt := makeReceipt(addr1) - gen.AddUncheckedReceipt(receipt) - case 1034: - receipt := makeReceipt(addr2) - gen.AddUncheckedReceipt(receipt) - case 34: - receipt := makeReceipt(addr3) - gen.AddUncheckedReceipt(receipt) - case 99999: - receipt := makeReceipt(addr4) - gen.AddUncheckedReceipt(receipt) - } - }) - for i, block := range chain { - rawdb.WriteBlock(backend.db, block) - rawdb.WriteCanonicalHash(backend.db, block.Hash(), block.NumberU64()) - rawdb.WriteHeadBlockHash(backend.db, block.Hash()) - rawdb.WriteReceipts(backend.db, block.Hash(), block.NumberU64(), receipts[i]) - } - b.ResetTimer() - - filter := NewRangeFilter(backend, testConfig(), 0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil) - - for i := 0; i < b.N; i++ { - logs, _ := filter.Logs(context.Background()) - if len(logs) != 4 { - // TODO: fix it - b.Fatal("expected 4 logs, got", len(logs)) - } - } -} - -func TestFilters(t *testing.T) { - var ( - backend = newTestBackend() - key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr = crypto.PubkeyToAddress(key1.PublicKey) - - hash1 = common.BytesToHash([]byte("topic1")) - hash2 = common.BytesToHash([]byte("topic2")) - hash3 = common.BytesToHash([]byte("topic3")) - hash4 = common.BytesToHash([]byte("topic4")) - ) - - genesis := core.GenesisBlockForTesting(backend.db, addr, big.NewInt(1000000)) - chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), backend.db, 1000, func(i int, gen *core.BlockGen) { - switch i { - case 1: - receipt := types.NewReceipt(nil, false, 0) - receipt.Logs = []*types.Log{ - { - BlockNumber: 1, - Address: addr, - Topics: []common.Hash{hash1}, - }, - } - gen.AddUncheckedReceipt(receipt) - gen.AddUncheckedTx(types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil)) - backend.MustPushLogs(receipt.Logs...) - - case 2: - receipt := types.NewReceipt(nil, false, 0) - receipt.Logs = []*types.Log{ - { - BlockNumber: 2, - Address: addr, - Topics: []common.Hash{hash2}, - }, - } - gen.AddUncheckedReceipt(receipt) - gen.AddUncheckedTx(types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil)) - backend.MustPushLogs(receipt.Logs...) - - case 998: - receipt := types.NewReceipt(nil, false, 0) - receipt.Logs = []*types.Log{ - { - BlockNumber: 998, - Address: addr, - Topics: []common.Hash{hash3}, - }, - } - gen.AddUncheckedReceipt(receipt) - gen.AddUncheckedTx(types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, big.NewInt(998), nil)) - backend.MustPushLogs(receipt.Logs...) - - case 999: - receipt := types.NewReceipt(nil, false, 0) - receipt.Logs = []*types.Log{ - { - Address: addr, - Topics: []common.Hash{hash4}, - }, - } - gen.AddUncheckedReceipt(receipt) - gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, big.NewInt(999), nil)) - backend.MustPushLogs(receipt.Logs...) - } - }) - for i, block := range chain { - rawdb.WriteBlock(backend.db, block) - rawdb.WriteCanonicalHash(backend.db, block.Hash(), block.NumberU64()) - rawdb.WriteHeadBlockHash(backend.db, block.Hash()) - rawdb.WriteReceipts(backend.db, block.Hash(), block.NumberU64(), receipts[i]) - } - - var ( - filter *Filter - logs []*types.Log - err error - ) - - filter = NewRangeFilter(backend, testConfig(), 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}}) - logs, err = filter.Logs(context.Background()) - if err != nil { - t.Error(err) - } - if len(logs) != 4 { - t.Error("expected 4 log, got", len(logs)) - } - - filter = NewRangeFilter(backend, testConfig(), 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}}) - logs, err = filter.Logs(context.Background()) - if err != nil { - t.Error(err) - } - if len(logs) != 1 { - t.Error("expected 1 log, got", len(logs)) - } - - if len(logs) > 0 && logs[0].Topics[0] != hash3 { - t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0]) - } - - filter = NewRangeFilter(backend, testConfig(), 990, -1, []common.Address{addr}, [][]common.Hash{{hash3}}) - logs, err = filter.Logs(context.Background()) - if err != nil { - t.Error(err) - } - if len(logs) != 1 { - t.Error("expected 1 log, got", len(logs)) - } - if len(logs) > 0 && logs[0].Topics[0] != hash3 { - t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0]) - } - - filter = NewRangeFilter(backend, testConfig(), 1, 10, nil, [][]common.Hash{{hash1, hash2}}) - logs, err = filter.Logs(context.Background()) - if err != nil { - t.Error(err) - } - if len(logs) != 2 { - t.Error("expected 2 log, got", len(logs)) - } - - failHash := common.BytesToHash([]byte("fail")) - filter = NewRangeFilter(backend, testConfig(), 0, -1, nil, [][]common.Hash{{failHash}}) - logs, err = filter.Logs(context.Background()) - if err != nil { - t.Error(err) - } - if len(logs) != 0 { - t.Error("expected 0 log, got", len(logs)) - } - - failAddr := common.BytesToAddress([]byte("failmenow")) - filter = NewRangeFilter(backend, testConfig(), 0, -1, []common.Address{failAddr}, nil) - logs, err = filter.Logs(context.Background()) - if err != nil { - t.Error(err) - } - if len(logs) != 0 { - t.Error("expected 0 log, got", len(logs)) - } - - filter = NewRangeFilter(backend, testConfig(), 0, -1, nil, [][]common.Hash{{failHash}, {hash1}}) - logs, err = filter.Logs(context.Background()) - if err != nil { - t.Error(err) - } - if len(logs) != 0 { - t.Error("expected 0 log, got", len(logs)) - } - -} diff --git a/evm/go-x1/gossip/gasprice/constructive.go b/evm/go-x1/gossip/gasprice/constructive.go deleted file mode 100644 index 1a01554..0000000 --- a/evm/go-x1/gossip/gasprice/constructive.go +++ /dev/null @@ -1,82 +0,0 @@ -package gasprice - -import ( - "math/big" - - "github.com/Fantom-foundation/lachesis-base/utils/piecefunc" -) - -func (gpo *Oracle) maxTotalGasPower() *big.Int { - rules := gpo.backend.GetRules() - - allocBn := new(big.Int).SetUint64(rules.Economy.LongGasPower.AllocPerSec) - periodBn := new(big.Int).SetUint64(uint64(rules.Economy.LongGasPower.MaxAllocPeriod)) - maxTotalGasPowerBn := new(big.Int).Mul(allocBn, periodBn) - maxTotalGasPowerBn.Div(maxTotalGasPowerBn, secondBn) - return maxTotalGasPowerBn -} - -func (gpo *Oracle) effectiveMinGasPrice() *big.Int { - return gpo.constructiveGasPrice(0, 0, gpo.backend.GetRules().Economy.MinGasPrice) -} - -func (gpo *Oracle) constructiveGasPrice(gasOffestAbs uint64, gasOffestRatio uint64, adjustedMinPrice *big.Int) *big.Int { - max := gpo.maxTotalGasPower() - - current64 := gpo.backend.TotalGasPowerLeft() - if current64 > gasOffestAbs { - current64 -= gasOffestAbs - } else { - current64 = 0 - } - current := new(big.Int).SetUint64(current64) - - freeRatioBn := current.Mul(current, DecimalUnitBn) - freeRatioBn.Div(freeRatioBn, max) - freeRatio := freeRatioBn.Uint64() - if freeRatio > gasOffestRatio { - freeRatio -= gasOffestRatio - } else { - freeRatio = 0 - } - if freeRatio > DecimalUnit { - freeRatio = DecimalUnit - } - v := gpo.constructiveGasPriceOf(freeRatio, adjustedMinPrice) - return v -} - -var freeRatioToConstructiveGasRatio = piecefunc.NewFunc([]piecefunc.Dot{ - { - X: 0, - Y: 25 * DecimalUnit, - }, - { - X: 0.3 * DecimalUnit, - Y: 9 * DecimalUnit, - }, - { - X: 0.5 * DecimalUnit, - Y: 3.75 * DecimalUnit, - }, - { - X: 0.8 * DecimalUnit, - Y: 1.5 * DecimalUnit, - }, - { - X: 0.95 * DecimalUnit, - Y: 1.05 * DecimalUnit, - }, - { - X: DecimalUnit, - Y: DecimalUnit, - }, -}) - -func (gpo *Oracle) constructiveGasPriceOf(freeRatio uint64, adjustedMinPrice *big.Int) *big.Int { - multiplier := new(big.Int).SetUint64(freeRatioToConstructiveGasRatio(freeRatio)) - - // gas price = multiplier * adjustedMinPrice - price := multiplier.Mul(multiplier, adjustedMinPrice) - return price.Div(price, DecimalUnitBn) -} diff --git a/evm/go-x1/gossip/gasprice/gasprice.go b/evm/go-x1/gossip/gasprice/gasprice.go deleted file mode 100644 index 4035a0b..0000000 --- a/evm/go-x1/gossip/gasprice/gasprice.go +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package gasprice - -import ( - "fmt" - "math/big" - "sync" - "time" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/piecefunc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/types" - lru "github.com/hashicorp/golang-lru" - - "github.com/Fantom-foundation/go-opera/opera" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" -) - -var ( - DefaultMaxGasPrice = big.NewInt(10000000 * params.GWei) - DecimalUnitBn = big.NewInt(DecimalUnit) - secondBn = new(big.Int).SetUint64(uint64(time.Second)) -) - -const ( - AsDefaultCertainty = math.MaxUint64 - DecimalUnit = piecefunc.DecimalUnit -) - -type Config struct { - MaxGasPrice *big.Int `toml:",omitempty"` - MinGasPrice *big.Int `toml:",omitempty"` - MinGasTip *big.Int `toml:",omitempty"` - DefaultCertainty uint64 `toml:",omitempty"` -} - -type Reader interface { - GetLatestBlockIndex() idx.Block - TotalGasPowerLeft() uint64 - GetRules() opera.Rules - GetPendingRules() opera.Rules - PendingTxs() map[common.Address]types.Transactions -} - -type tipCache struct { - upd time.Time - tip *big.Int -} - -type effectiveMinGasPriceCache struct { - head idx.Block - lock sync.RWMutex - value *big.Int -} - -// Oracle recommends gas prices based on the content of recent -// blocks. Suitable for both light and full clients. -type Oracle struct { - backend Reader - - c circularTxpoolStats - - cfg Config - - eCache effectiveMinGasPriceCache - tCache *lru.Cache - - wg sync.WaitGroup - quit chan struct{} -} - -func sanitizeBigInt(val, min, max, _default *big.Int, name string) *big.Int { - if val == nil || (val.Sign() == 0 && _default.Sign() != 0) { - log.Warn(fmt.Sprintf("Sanitizing invalid parameter %s of gasprice oracle", name), "provided", val, "updated", _default) - return _default - } - if min != nil && val.Cmp(min) < 0 { - log.Warn(fmt.Sprintf("Sanitizing invalid parameter %s of gasprice oracle", name), "provided", val, "updated", min) - return min - } - if max != nil && val.Cmp(max) > 0 { - log.Warn(fmt.Sprintf("Sanitizing invalid parameter %s of gasprice oracle", name), "provided", val, "updated", max) - return max - } - return val -} - -// NewOracle returns a new gasprice oracle which can recommend suitable -// gasprice for newly created transaction. -func NewOracle(params Config) *Oracle { - params.MaxGasPrice = sanitizeBigInt(params.MaxGasPrice, nil, nil, DefaultMaxGasPrice, "MaxGasPrice") - params.MinGasPrice = sanitizeBigInt(params.MinGasPrice, nil, params.MaxGasPrice, new(big.Int), "MinGasPrice") - params.MinGasTip = sanitizeBigInt(params.MinGasTip, nil, new(big.Int).Sub(params.MaxGasPrice, params.MinGasPrice), new(big.Int), "MinGasTip") - params.DefaultCertainty = sanitizeBigInt(new(big.Int).SetUint64(params.DefaultCertainty), big.NewInt(0), DecimalUnitBn, big.NewInt(DecimalUnit/2), "DefaultCertainty").Uint64() - tCache, _ := lru.New(100) - return &Oracle{ - cfg: params, - tCache: tCache, - quit: make(chan struct{}), - } -} - -func (gpo *Oracle) Start(backend Reader) { - gpo.backend = backend - gpo.wg.Add(1) - go func() { - defer gpo.wg.Done() - gpo.txpoolStatsLoop() - }() -} - -func (gpo *Oracle) Stop() { - close(gpo.quit) - gpo.wg.Wait() -} - -func (gpo *Oracle) suggestTip(certainty uint64) *big.Int { - minPrice := gpo.backend.GetRules().Economy.MinGasPrice - pendingMinPrice := gpo.backend.GetPendingRules().Economy.MinGasPrice - adjustedMinGasPrice := math.BigMax(minPrice, pendingMinPrice) - - reactive := gpo.reactiveGasPrice(certainty) - constructive := gpo.constructiveGasPrice(gpo.c.totalGas(), 0.005*DecimalUnit+certainty/25, adjustedMinGasPrice) - - combined := math.BigMax(reactive, constructive) - if combined.Cmp(gpo.cfg.MinGasPrice) < 0 { - combined = gpo.cfg.MinGasPrice - } - if combined.Cmp(gpo.cfg.MaxGasPrice) > 0 { - combined = gpo.cfg.MaxGasPrice - } - - tip := new(big.Int).Sub(combined, minPrice) - if tip.Cmp(gpo.cfg.MinGasTip) < 0 { - return new(big.Int).Set(gpo.cfg.MinGasTip) - } - return tip -} - -// SuggestTip returns a tip cap so that newly created transaction can have a -// very high chance to be included in the following blocks. -// -// Note, for legacy transactions and the legacy eth_gasPrice RPC call, it will be -// necessary to add the basefee to the returned number to fall back to the legacy -// behavior. -func (gpo *Oracle) SuggestTip(certainty uint64) *big.Int { - if gpo.backend == nil { - return new(big.Int) - } - if certainty == AsDefaultCertainty { - certainty = gpo.cfg.DefaultCertainty - } - - const cacheSlack = DecimalUnit * 0.05 - roundedCertainty := certainty / cacheSlack - if cached, ok := gpo.tCache.Get(roundedCertainty); ok { - cache := cached.(tipCache) - if time.Since(cache.upd) < statUpdatePeriod { - return new(big.Int).Set(cache.tip) - } else { - gpo.tCache.Remove(roundedCertainty) - } - } - - tip := gpo.suggestTip(certainty) - - gpo.tCache.Add(roundedCertainty, tipCache{ - upd: time.Now(), - tip: tip, - }) - return new(big.Int).Set(tip) -} - -// EffectiveMinGasPrice returns softly enforced minimum gas price on top of on-chain minimum gas price (base fee) -func (gpo *Oracle) EffectiveMinGasPrice() *big.Int { - if gpo.backend == nil { - return new(big.Int).Set(gpo.cfg.MinGasPrice) - } - head := gpo.backend.GetLatestBlockIndex() - - // If the latest gasprice is still available, return it. - gpo.eCache.lock.RLock() - cachedHead, cachedValue := gpo.eCache.head, gpo.eCache.value - gpo.eCache.lock.RUnlock() - if head <= cachedHead { - return new(big.Int).Set(cachedValue) - } - - value := gpo.effectiveMinGasPrice() - - gpo.eCache.lock.Lock() - if head > gpo.eCache.head { - gpo.eCache.head = head - gpo.eCache.value = value - } - gpo.eCache.lock.Unlock() - return new(big.Int).Set(value) -} diff --git a/evm/go-x1/gossip/gasprice/gasprice_test.go b/evm/go-x1/gossip/gasprice/gasprice_test.go deleted file mode 100644 index ced401d..0000000 --- a/evm/go-x1/gossip/gasprice/gasprice_test.go +++ /dev/null @@ -1,325 +0,0 @@ -package gasprice - -import ( - "math/big" - "testing" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/opera" -) - -type fakeTx struct { - gas uint64 - tip *big.Int - cap *big.Int -} - -type TestBackend struct { - block idx.Block - totalGasPowerLeft uint64 - rules opera.Rules - pendingRules opera.Rules - pendingTxs []fakeTx -} - -func (t TestBackend) GetLatestBlockIndex() idx.Block { - return t.block -} - -func (t TestBackend) TotalGasPowerLeft() uint64 { - return t.totalGasPowerLeft -} - -func (t TestBackend) GetRules() opera.Rules { - return t.rules -} - -func (t TestBackend) GetPendingRules() opera.Rules { - return t.pendingRules -} - -func (t TestBackend) PendingTxs() map[common.Address]types.Transactions { - txs := make(map[common.Address]types.Transactions, len(t.pendingTxs)) - for i, tx := range t.pendingTxs { - txs[common.BytesToAddress(big.NewInt(int64(i)).Bytes())] = types.Transactions{ - types.NewTx(&types.DynamicFeeTx{ - Nonce: uint64(i), - GasTipCap: tx.tip, - GasFeeCap: tx.cap, - Gas: tx.gas, - }), - } - } - return txs -} - -func TestOracle_EffectiveMinGasPrice(t *testing.T) { - backend := &TestBackend{ - block: 1, - totalGasPowerLeft: 0, - rules: opera.FakeNetRules(), - pendingRules: opera.FakeNetRules(), - } - - gpo := NewOracle(Config{}) - gpo.cfg.MaxGasPrice = math.MaxBig256 - gpo.cfg.MinGasPrice = new(big.Int) - - // no backend - require.Equal(t, "0", gpo.EffectiveMinGasPrice().String()) - gpo.backend = backend - - // all the gas is consumed, price should be high - backend.block++ - backend.totalGasPowerLeft = 0 - require.Equal(t, "25000000000", gpo.EffectiveMinGasPrice().String()) - - // test the cache as well - backend.totalGasPowerLeft = 1008000000 - require.Equal(t, "25000000000", gpo.EffectiveMinGasPrice().String()) - backend.block++ - require.Equal(t, "24994672000", gpo.EffectiveMinGasPrice().String()) - backend.block++ - - // all the gas is free, price should be low - backend.totalGasPowerLeft = gpo.maxTotalGasPower().Uint64() - require.Equal(t, uint64(0x92aeed1c000), backend.totalGasPowerLeft) - require.Equal(t, "1000000000", gpo.EffectiveMinGasPrice().String()) - backend.block++ - - // edge case with totalGasPowerLeft exceeding maxTotalGasPower - backend.totalGasPowerLeft = 2 * gpo.maxTotalGasPower().Uint64() - require.Equal(t, "1000000000", gpo.EffectiveMinGasPrice().String()) - backend.block++ - - // half of the gas is free, price should be 3.75x - backend.totalGasPowerLeft = gpo.maxTotalGasPower().Uint64() / 2 - require.Equal(t, "3750000000", gpo.EffectiveMinGasPrice().String()) - backend.block++ - - // third of the gas is free, price should be higher - backend.totalGasPowerLeft = gpo.maxTotalGasPower().Uint64() / 3 - require.Equal(t, "8125008000", gpo.EffectiveMinGasPrice().String()) - backend.block++ - - // check min and max price hard limits don't apply - gpo.cfg.MaxGasPrice = big.NewInt(2000000000) - backend.totalGasPowerLeft = gpo.maxTotalGasPower().Uint64() / 3 - require.Equal(t, "8125008000", gpo.EffectiveMinGasPrice().String()) - backend.block++ - - gpo.cfg.MinGasPrice = big.NewInt(1500000000) - backend.totalGasPowerLeft = gpo.maxTotalGasPower().Uint64() - require.Equal(t, "1000000000", gpo.EffectiveMinGasPrice().String()) - backend.block++ -} - -func TestOracle_constructiveGasPrice(t *testing.T) { - backend := &TestBackend{ - totalGasPowerLeft: 0, - rules: opera.FakeNetRules(), - pendingRules: opera.FakeNetRules(), - } - - gpo := NewOracle(Config{}) - gpo.backend = backend - gpo.cfg.MaxGasPrice = math.MaxBig256 - gpo.cfg.MinGasPrice = new(big.Int) - - // all the gas is consumed, price should be high - backend.totalGasPowerLeft = 0 - require.Equal(t, "2500", gpo.constructiveGasPrice(0, 0, big.NewInt(100)).String()) - require.Equal(t, "2500", gpo.constructiveGasPrice(0, 0.1*DecimalUnit, big.NewInt(100)).String()) - require.Equal(t, "2500", gpo.constructiveGasPrice(1008000000, 0, big.NewInt(100)).String()) - require.Equal(t, "2500", gpo.constructiveGasPrice(gpo.maxTotalGasPower().Uint64()*2, 2*DecimalUnit, big.NewInt(100)).String()) - - // all the gas is free, price should be low - backend.totalGasPowerLeft = gpo.maxTotalGasPower().Uint64() - require.Equal(t, "100", gpo.constructiveGasPrice(0, 0, big.NewInt(100)).String()) - require.Equal(t, "120", gpo.constructiveGasPrice(0, 0.1*DecimalUnit, big.NewInt(100)).String()) - require.Equal(t, "101", gpo.constructiveGasPrice(100800000000, 0, big.NewInt(100)).String()) - require.Equal(t, "2500", gpo.constructiveGasPrice(gpo.maxTotalGasPower().Uint64()*2, 2*DecimalUnit, big.NewInt(100)).String()) - - // half of the gas is free, price should be 3.75x - backend.totalGasPowerLeft = gpo.maxTotalGasPower().Uint64() / 2 - require.Equal(t, "375", gpo.constructiveGasPrice(0, 0, big.NewInt(100)).String()) - require.Equal(t, "637", gpo.constructiveGasPrice(0, 0.1*DecimalUnit, big.NewInt(100)).String()) - require.Equal(t, "401", gpo.constructiveGasPrice(100800000000, 0, big.NewInt(100)).String()) - require.Equal(t, "2500", gpo.constructiveGasPrice(gpo.maxTotalGasPower().Uint64()*2, 2*DecimalUnit, big.NewInt(100)).String()) - - // third of the gas is free, price should be higher - backend.totalGasPowerLeft = gpo.maxTotalGasPower().Uint64() / 3 - require.Equal(t, "812", gpo.constructiveGasPrice(0, 0, big.NewInt(100)).String()) - require.Equal(t, "1255", gpo.constructiveGasPrice(0, 0.1*DecimalUnit, big.NewInt(100)).String()) - require.Equal(t, "838", gpo.constructiveGasPrice(100800000000, 0, big.NewInt(100)).String()) - require.Equal(t, "2500", gpo.constructiveGasPrice(gpo.maxTotalGasPower().Uint64()*2, 2*DecimalUnit, big.NewInt(100)).String()) - -} - -func TestOracle_reactiveGasPrice(t *testing.T) { - backend := &TestBackend{ - totalGasPowerLeft: 0, - rules: opera.FakeNetRules(), - pendingRules: opera.FakeNetRules(), - } - - gpo := NewOracle(Config{}) - gpo.backend = backend - gpo.cfg.MaxGasPrice = math.MaxBig256 - gpo.cfg.MinGasPrice = new(big.Int) - - // no stats -> zero price - gpo.c = circularTxpoolStats{} - require.Equal(t, "0", gpo.reactiveGasPrice(0).String()) - require.Equal(t, "0", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0).String()) - require.Equal(t, "0", gpo.reactiveGasPrice(DecimalUnit).String()) - - // one tx - gpo.c = circularTxpoolStats{} - backend.pendingTxs = append(backend.pendingTxs, fakeTx{ - gas: 50000, - tip: big.NewInt(0), - cap: big.NewInt(1e9), - }) - require.Equal(t, "0", gpo.reactiveGasPrice(0).String()) - require.Equal(t, "0", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0).String()) - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "200000000", gpo.reactiveGasPrice(0.9*DecimalUnit).String()) - require.Equal(t, "600000000", gpo.reactiveGasPrice(0.95*DecimalUnit).String()) - require.Equal(t, "920000000", gpo.reactiveGasPrice(0.99*DecimalUnit).String()) - require.Equal(t, "1000000000", gpo.reactiveGasPrice(DecimalUnit).String()) - - // add one more tx - backend.pendingTxs = append(backend.pendingTxs, fakeTx{ - gas: 25000, - tip: big.NewInt(3 * 1e9), - cap: big.NewInt(3.5 * 1e9), - }) - - require.Equal(t, "0", gpo.reactiveGasPrice(0).String()) - require.Equal(t, "1000000000", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0).String()) - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "450000000", gpo.reactiveGasPrice(0.9*DecimalUnit).String()) - require.Equal(t, "1350000000", gpo.reactiveGasPrice(0.95*DecimalUnit).String()) - require.Equal(t, "2070000000", gpo.reactiveGasPrice(0.99*DecimalUnit).String()) - require.Equal(t, "2250000000", gpo.reactiveGasPrice(DecimalUnit).String()) - - // add two more txs - backend.pendingTxs = append(backend.pendingTxs, fakeTx{ - gas: 2500000, - tip: big.NewInt(1 * 1e9), - cap: big.NewInt(3.5 * 1e9), - }) - backend.pendingTxs = append(backend.pendingTxs, fakeTx{ - gas: 2500000, - tip: big.NewInt(0 * 1e9), - cap: big.NewInt(3.5 * 1e9), - }) - - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0).String()) - require.Equal(t, "333333333", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "799999999", gpo.reactiveGasPrice(0.9*DecimalUnit).String()) - require.Equal(t, "1733333332", gpo.reactiveGasPrice(0.95*DecimalUnit).String()) - require.Equal(t, "2479999999", gpo.reactiveGasPrice(0.99*DecimalUnit).String()) - require.Equal(t, "2666666666", gpo.reactiveGasPrice(DecimalUnit).String()) - // price gets closer to latest state - gpo.txpoolStatsTick() - require.Equal(t, "500000000", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "2875000000", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "600000000", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000000", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "666666666", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3083333333", gpo.reactiveGasPrice(DecimalUnit).String()) - for i := 0; i < statsBuffer-5; i++ { - gpo.txpoolStatsTick() - } - require.Equal(t, "933333333", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3500000000", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "1000000000", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3500000000", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "1000000000", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3500000000", gpo.reactiveGasPrice(DecimalUnit).String()) - - // change minGasPrice - backend.rules.Economy.MinGasPrice = big.NewInt(100) - gpo.txpoolStatsTick() - require.Equal(t, "933333340", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3466666673", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "866666680", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3433333346", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "800000020", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3400000020", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - // recent gas price plus 5% - require.Equal(t, "105", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3150000105", gpo.reactiveGasPrice(DecimalUnit).String()) - for i := 0; i < statsBuffer-5; i++ { - gpo.txpoolStatsTick() - } - require.Equal(t, "105", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3033333426", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "100", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000100", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "100", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000100", gpo.reactiveGasPrice(DecimalUnit).String()) - - // half of txs are confirmed now - backend.pendingTxs = backend.pendingTxs[:2] - gpo.txpoolStatsTick() - require.Equal(t, "93", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000100", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "86", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000100", gpo.reactiveGasPrice(DecimalUnit).String()) - for i := 0; i < statsBuffer-3; i++ { - gpo.txpoolStatsTick() - } - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000100", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000100", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000100", gpo.reactiveGasPrice(DecimalUnit).String()) - - // all txs are confirmed now - backend.pendingTxs = backend.pendingTxs[:0] - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000100", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "3000000100", gpo.reactiveGasPrice(DecimalUnit).String()) - for i := 0; i < statsBuffer-3; i++ { - gpo.txpoolStatsTick() - } - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "0", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "0", gpo.reactiveGasPrice(DecimalUnit).String()) - gpo.txpoolStatsTick() - require.Equal(t, "0", gpo.reactiveGasPrice(0.8*DecimalUnit).String()) - require.Equal(t, "0", gpo.reactiveGasPrice(DecimalUnit).String()) -} diff --git a/evm/go-x1/gossip/gasprice/reactive.go b/evm/go-x1/gossip/gasprice/reactive.go deleted file mode 100644 index 9873af1..0000000 --- a/evm/go-x1/gossip/gasprice/reactive.go +++ /dev/null @@ -1,260 +0,0 @@ -package gasprice - -import ( - "math/big" - "sort" - "sync/atomic" - "time" - - "github.com/Fantom-foundation/lachesis-base/utils/piecefunc" - "github.com/ethereum/go-ethereum/core/types" -) - -const ( - percentilesPerStat = 20 - statUpdatePeriod = 1 * time.Second - statsBuffer = int((15 * time.Second) / statUpdatePeriod) - maxGasToIndex = 40000000 -) - -type txpoolStat struct { - totalGas uint64 - percentiles [percentilesPerStat]*big.Int -} - -type circularTxpoolStats struct { - stats [statsBuffer]txpoolStat - i int - activated uint32 - avg atomic.Value -} - -var certaintyToGasAbove = piecefunc.NewFunc([]piecefunc.Dot{ - { - X: 0, - Y: 50000000, - }, - { - X: 0.2 * DecimalUnit, - Y: 20000000, - }, - { - X: 0.5 * DecimalUnit, - Y: 8000000, - }, - { - X: DecimalUnit, - Y: 0, - }, -}) - -func (gpo *Oracle) reactiveGasPrice(certainty uint64) *big.Int { - gasAbove := certaintyToGasAbove(certainty) - - return gpo.c.getGasPriceForGasAbove(gasAbove) -} - -func (gpo *Oracle) txpoolStatsTick() { - c := &gpo.c - // calculate txpool statistic and push into the circular buffer - c.stats[c.i] = gpo.calcTxpoolStat() - c.i = (c.i + 1) % len(c.stats) - // calculate average of statistics in the circular buffer - c.avg.Store(c.calcAvg()) -} - -func (gpo *Oracle) txpoolStatsLoop() { - ticker := time.NewTicker(statUpdatePeriod) - defer ticker.Stop() - for i := uint32(0); ; i++ { - select { - case <-ticker.C: - // calculate more frequently after first request - if atomic.LoadUint32(&gpo.c.activated) != 0 || i%5 == 0 { - gpo.txpoolStatsTick() - } - case <-gpo.quit: - return - } - } -} - -func (c *circularTxpoolStats) dec(v int) int { - if v == 0 { - return len(c.stats) - 1 - } - return v - 1 -} - -// calcAvg calculates average of statistics in the circular buffer -func (c *circularTxpoolStats) calcAvg() txpoolStat { - avg := txpoolStat{} - for p := range avg.percentiles { - avg.percentiles[p] = new(big.Int) - } - nonZero := uint64(0) - for _, s := range c.stats { - if s.totalGas == 0 { - continue - } - nonZero++ - avg.totalGas += s.totalGas - for p := range s.percentiles { - if s.percentiles[p] == nil { - continue - } - avg.percentiles[p].Add(avg.percentiles[p], s.percentiles[p]) - } - } - if nonZero == 0 { - return avg - } - avg.totalGas /= nonZero - nonZeroBn := new(big.Int).SetUint64(nonZero) - for p := range avg.percentiles { - avg.percentiles[p].Div(avg.percentiles[p], nonZeroBn) - } - - // take maximum from previous 4 stats plus 5% - rec := txpoolStat{} - for p := range rec.percentiles { - rec.percentiles[p] = new(big.Int) - } - recI1 := c.dec(c.i) - recI2 := c.dec(recI1) - recI3 := c.dec(recI2) - recI4 := c.dec(recI3) - for _, s := range []txpoolStat{c.stats[recI1], c.stats[recI2], c.stats[recI3], c.stats[recI4]} { - for p := range s.percentiles { - if s.percentiles[p] == nil { - continue - } - if rec.percentiles[p].Cmp(s.percentiles[p]) < 0 { - rec.percentiles[p].Set(s.percentiles[p]) - } - } - } - // increase by 5% - for p := range rec.percentiles { - rec.percentiles[p].Mul(rec.percentiles[p], big.NewInt(21)) - rec.percentiles[p].Div(rec.percentiles[p], big.NewInt(20)) - } - - // return minimum from max(recent two stats * 1.05) and avg stats - res := txpoolStat{} - res.totalGas = avg.totalGas - for _, s := range []txpoolStat{avg, rec} { - for p := range s.percentiles { - if res.percentiles[p] == nil || res.percentiles[p].Cmp(s.percentiles[p]) > 0 { - res.percentiles[p] = s.percentiles[p] - } - } - } - - return res -} - -func (c *circularTxpoolStats) getGasPriceForGasAbove(gas uint64) *big.Int { - atomic.StoreUint32(&c.activated, 1) - avg_c := c.avg.Load() - if avg_c == nil { - return new(big.Int) - } - avg := avg_c.(txpoolStat) - if avg.totalGas == 0 { - return new(big.Int) - } - if gas > maxGasToIndex { - // extrapolate linearly - v := new(big.Int).Mul(avg.percentiles[len(avg.percentiles)-1], new(big.Int).SetUint64(maxGasToIndex)) - v.Div(v, new(big.Int).SetUint64(gas+1)) - return v - } - p0 := gas * uint64(len(avg.percentiles)) / maxGasToIndex - if p0 >= uint64(len(avg.percentiles))-1 { - return avg.percentiles[len(avg.percentiles)-1] - } - // interpolate linearly - p1 := p0 + 1 - x := gas - x0, x1 := p0*maxGasToIndex/uint64(len(avg.percentiles)), p1*maxGasToIndex/uint64(len(avg.percentiles)) - y0, y1 := avg.percentiles[p0], avg.percentiles[p1] - return div64I(addBigI(mul64N(y0, x1-x), mul64N(y1, x-x0)), x1-x0) -} - -func mul64N(a *big.Int, b uint64) *big.Int { - return new(big.Int).Mul(a, new(big.Int).SetUint64(b)) -} - -func div64I(a *big.Int, b uint64) *big.Int { - return a.Div(a, new(big.Int).SetUint64(b)) -} - -func addBigI(a, b *big.Int) *big.Int { - return a.Add(a, b) -} - -func (c *circularTxpoolStats) totalGas() uint64 { - atomic.StoreUint32(&c.activated, 1) - avgC := c.avg.Load() - if avgC == nil { - return 0 - } - avg := avgC.(txpoolStat) - return avg.totalGas -} - -// calcTxpoolStat retrieves txpool transactions and calculates statistics -func (gpo *Oracle) calcTxpoolStat() txpoolStat { - txsMap := gpo.backend.PendingTxs() - s := txpoolStat{} - if len(txsMap) == 0 { - // short circuit if empty txpool - return s - } - // take only one tx from each account - txs := make(types.Transactions, 0, 1000) - for _, aTxs := range txsMap { - txs = append(txs, aTxs[0]) - } - - // don't index more transactions than needed for GPO purposes - const maxTxsToIndex = 400 - - minGasPrice := gpo.backend.GetRules().Economy.MinGasPrice - // txs are sorted from large price to small - sorted := txs - sort.Slice(sorted, func(i, j int) bool { - a, b := sorted[i], sorted[j] - cmp := a.EffectiveGasTipCmp(b, minGasPrice) - if cmp == 0 { - return a.Gas() > b.Gas() - } - return cmp > 0 - }) - - for i, tx := range sorted { - s.totalGas += tx.Gas() - if s.totalGas > maxGasToIndex || i > maxTxsToIndex { - sorted = sorted[:i+1] - break - } - } - - gasCounter := uint64(0) - p := uint64(0) - for _, tx := range sorted { - for p < uint64(len(s.percentiles)) && gasCounter >= p*maxGasToIndex/uint64(len(s.percentiles)) { - s.percentiles[p] = tx.EffectiveGasTipValue(minGasPrice) - if s.percentiles[p].Sign() < 0 { - s.percentiles[p] = minGasPrice - } else { - s.percentiles[p].Add(s.percentiles[p], minGasPrice) - } - p++ - } - gasCounter += tx.Gas() - } - - return s -} diff --git a/evm/go-x1/gossip/gpo_backend.go b/evm/go-x1/gossip/gpo_backend.go deleted file mode 100644 index 1b4f9ba..0000000 --- a/evm/go-x1/gossip/gpo_backend.go +++ /dev/null @@ -1,96 +0,0 @@ -package gossip - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/eventcheck/gaspowercheck" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/utils/concurrent" -) - -type GPOBackend struct { - store *Store - txpool TxPool -} - -func (b *GPOBackend) GetLatestBlockIndex() idx.Block { - return b.store.GetLatestBlockIndex() -} - -func (b *GPOBackend) GetRules() opera.Rules { - return b.store.GetRules() -} - -func (b *GPOBackend) GetPendingRules() opera.Rules { - bs, es := b.store.GetBlockEpochState() - if bs.DirtyRules != nil { - return *bs.DirtyRules - } - return es.Rules -} - -func (b *GPOBackend) PendingTxs() map[common.Address]types.Transactions { - txs, err := b.txpool.Pending(false) - if err != nil { - return map[common.Address]types.Transactions{} - } - return txs -} - -// TotalGasPowerLeft returns a total amount of obtained gas power by the validators, according to the latest events from each validator -func (b *GPOBackend) TotalGasPowerLeft() uint64 { - bs, es := b.store.GetBlockEpochState() - set := b.store.GetLastEvents(es.Epoch) - if set == nil { - set = concurrent.WrapValidatorEventsSet(map[idx.ValidatorID]hash.Event{}) - } - set.RLock() - defer set.RUnlock() - metValidators := map[idx.ValidatorID]bool{} - total := uint64(0) - gasPowerCheckCfg := gaspowercheck.Config{ - Idx: inter.LongTermGas, - AllocPerSec: es.Rules.Economy.LongGasPower.AllocPerSec, - MaxAllocPeriod: es.Rules.Economy.LongGasPower.MaxAllocPeriod, - MinEnsuredAlloc: es.Rules.Economy.Gas.MaxEventGas, - StartupAllocPeriod: es.Rules.Economy.LongGasPower.StartupAllocPeriod, - MinStartupGas: es.Rules.Economy.LongGasPower.MinStartupGas, - } - // count GasPowerLeft from latest events of this epoch - for _, tip := range set.Val { - e := b.store.GetEvent(tip) - left := e.GasPowerLeft().Gas[inter.LongTermGas] - left += bs.GetValidatorState(e.Creator(), es.Validators).DirtyGasRefund - - _, max, _ := gaspowercheck.CalcValidatorGasPowerPerSec(e.Creator(), es.Validators, gasPowerCheckCfg) - if left > max { - left = max - } - total += left - - metValidators[e.Creator()] = true - } - // count GasPowerLeft from last events of prev epoch if no event in current epoch is present - for i := idx.Validator(0); i < es.Validators.Len(); i++ { - vid := es.Validators.GetID(i) - if !metValidators[vid] { - left := es.ValidatorStates[i].PrevEpochEvent.GasPowerLeft.Gas[inter.LongTermGas] - left += es.ValidatorStates[i].GasRefund - - _, max, startup := gaspowercheck.CalcValidatorGasPowerPerSec(vid, es.Validators, gasPowerCheckCfg) - if left > max { - left = max - } - if left < startup { - left = startup - } - total += left - } - } - - return total -} diff --git a/evm/go-x1/gossip/handler.go b/evm/go-x1/gossip/handler.go deleted file mode 100644 index ef2e22a..0000000 --- a/evm/go-x1/gossip/handler.go +++ /dev/null @@ -1,1538 +0,0 @@ -package gossip - -import ( - "errors" - "fmt" - "math" - "math/rand" - "strings" - "sync" - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/dagprocessor" - "github.com/Fantom-foundation/lachesis-base/gossip/itemsfetcher" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/datasemaphore" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - notify "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/discover/discfilter" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" - - "github.com/Fantom-foundation/go-opera/eventcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/bvallcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/epochcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/evallcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/heavycheck" - "github.com/Fantom-foundation/go-opera/eventcheck/parentlesscheck" - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brprocessor" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brstream" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brstream/brstreamleecher" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brstream/brstreamseeder" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvprocessor" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvstream" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvstream/bvstreamleecher" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvstream/bvstreamseeder" - "github.com/Fantom-foundation/go-opera/gossip/protocols/dag/dagstream" - "github.com/Fantom-foundation/go-opera/gossip/protocols/dag/dagstream/dagstreamleecher" - "github.com/Fantom-foundation/go-opera/gossip/protocols/dag/dagstream/dagstreamseeder" - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epprocessor" - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epstream" - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epstream/epstreamleecher" - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epstream/epstreamseeder" - "github.com/Fantom-foundation/go-opera/gossip/protocols/snap/snapstream/snapleecher" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/utils/txtime" -) - -const ( - softResponseLimitSize = 2 * 1024 * 1024 // Target maximum size of returned events, or other data. - softLimitItems = 250 // Target maximum number of events or transactions to request/response - hardLimitItems = softLimitItems * 4 // Maximum number of events or transactions to request/response - - // txChanSize is the size of channel listening to NewTxsNotify. - // The number is referenced from the size of tx pool. - txChanSize = 4096 -) - -func errResp(code errCode, format string, v ...interface{}) error { - return fmt.Errorf("%v - %v", code, fmt.Sprintf(format, v...)) -} - -func checkLenLimits(size int, v interface{}) error { - if size <= 0 { - return errResp(ErrEmptyMessage, "%v", v) - } - if size > hardLimitItems { - return errResp(ErrMsgTooLarge, "%v", v) - } - return nil -} - -type dagNotifier interface { - SubscribeNewEpoch(ch chan<- idx.Epoch) notify.Subscription - SubscribeNewEmitted(ch chan<- *inter.EventPayload) notify.Subscription -} - -type processCallback struct { - Event func(*inter.EventPayload) error - SwitchEpochTo func(idx.Epoch) error - PauseEvmSnapshot func() - BVs func(inter.LlrSignedBlockVotes) error - BR func(ibr.LlrIdxFullBlockRecord) error - EV func(inter.LlrSignedEpochVote) error - ER func(ier.LlrIdxFullEpochRecord) error -} - -// handlerConfig is the collection of initialization parameters to create a full -// node network handler. -type handlerConfig struct { - config Config - notifier dagNotifier - txpool TxPool - engineMu sync.Locker - checkers *eventcheck.Checkers - s *Store - process processCallback -} - -type snapsyncEpochUpd struct { - epoch idx.Epoch - root common.Hash -} - -type snapsyncCancelCmd struct { - done chan struct{} -} - -type snapsyncStateUpd struct { - snapsyncEpochUpd *snapsyncEpochUpd - snapsyncCancelCmd *snapsyncCancelCmd -} - -type snapsyncState struct { - epoch idx.Epoch - cancel func() error - updatesCh chan snapsyncStateUpd - quit chan struct{} -} - -type handler struct { - NetworkID uint64 - config Config - - syncStatus syncStatus - - txpool TxPool - maxPeers int - - peers *peerSet - - txsCh chan evmcore.NewTxsNotify - txsSub notify.Subscription - - dagLeecher *dagstreamleecher.Leecher - dagSeeder *dagstreamseeder.Seeder - dagProcessor *dagprocessor.Processor - dagFetcher *itemsfetcher.Fetcher - - bvLeecher *bvstreamleecher.Leecher - bvSeeder *bvstreamseeder.Seeder - bvProcessor *bvprocessor.Processor - - brLeecher *brstreamleecher.Leecher - brSeeder *brstreamseeder.Seeder - brProcessor *brprocessor.Processor - - epLeecher *epstreamleecher.Leecher - epSeeder *epstreamseeder.Seeder - epProcessor *epprocessor.Processor - - process processCallback - - txFetcher *itemsfetcher.Fetcher - - checkers *eventcheck.Checkers - - msgSemaphore *datasemaphore.DataSemaphore - - store *Store - engineMu sync.Locker - - notifier dagNotifier - emittedEventsCh chan *inter.EventPayload - emittedEventsSub notify.Subscription - newEpochsCh chan idx.Epoch - newEpochsSub notify.Subscription - quitProgressBradcast chan struct{} - - // channels for syncer, txsyncLoop - txsyncCh chan *txsync - quitSync chan struct{} - - // snapsync fields - chain *ethBlockChain - snapLeecher *snapleecher.Leecher - snapState snapsyncState - - // wait group is used for graceful shutdowns during downloading - // and processing - loopsWg sync.WaitGroup - wg sync.WaitGroup - peerWG sync.WaitGroup - started sync.WaitGroup - - logger.Instance -} - -// newHandler returns a new Fantom sub protocol manager. The Fantom sub protocol manages peers capable -// with the Fantom network. -func newHandler( - c handlerConfig, -) ( - *handler, - error, -) { - // Create the protocol manager with the base fields - h := &handler{ - NetworkID: c.s.GetRules().NetworkID, - config: c.config, - notifier: c.notifier, - txpool: c.txpool, - msgSemaphore: datasemaphore.New(c.config.Protocol.MsgsSemaphoreLimit, getSemaphoreWarningFn("P2P messages")), - store: c.s, - process: c.process, - checkers: c.checkers, - peers: newPeerSet(), - engineMu: c.engineMu, - txsyncCh: make(chan *txsync), - quitSync: make(chan struct{}), - quitProgressBradcast: make(chan struct{}), - - snapState: snapsyncState{ - updatesCh: make(chan snapsyncStateUpd, 128), - quit: make(chan struct{}), - }, - - Instance: logger.New("PM"), - } - h.started.Add(1) - - // TODO: configure it - var ( - configBloomCache uint64 = 0 // Megabytes to alloc for fast sync bloom - ) - - var err error - h.chain, err = newEthBlockChain(c.s) - if err != nil { - return nil, err - } - - stateDb := h.store.EvmStore().EvmDb - var stateBloom *trie.SyncBloom - if false { - // NOTE: Construct the downloader (long sync) and its backing state bloom if fast - // sync is requested. The downloader is responsible for deallocating the state - // bloom when it's done. - // Note: we don't enable it if snap-sync is performed, since it's very heavy - // and the heal-portion of the snap sync is much lighter than fast. What we particularly - // want to avoid, is a 90%-finished (but restarted) snap-sync to begin - // indexing the entire trie - stateBloom = trie.NewSyncBloom(configBloomCache, stateDb) - } - h.snapLeecher = snapleecher.New(stateDb, stateBloom, h.removePeer) - - h.dagFetcher = itemsfetcher.New(h.config.Protocol.DagFetcher, itemsfetcher.Callback{ - OnlyInterested: func(ids []interface{}) []interface{} { - return h.onlyInterestedEventsI(ids) - }, - Suspend: func() bool { - return false - }, - }) - h.txFetcher = itemsfetcher.New(h.config.Protocol.TxFetcher, itemsfetcher.Callback{ - OnlyInterested: func(txids []interface{}) []interface{} { - return txidsToInterfaces(h.txpool.OnlyNotExisting(interfacesToTxids(txids))) - }, - Suspend: func() bool { - return false - }, - }) - - h.dagProcessor = h.makeDagProcessor(c.checkers) - h.dagLeecher = dagstreamleecher.New(h.store.GetEpoch(), h.store.GetHighestLamport() == 0, h.config.Protocol.DagStreamLeecher, dagstreamleecher.Callbacks{ - IsProcessed: h.store.HasEvent, - RequestChunk: func(peer string, r dagstream.Request) error { - p := h.peers.Peer(peer) - if p == nil { - return errNotRegistered - } - return p.RequestEventsStream(r) - }, - Suspend: func(_ string) bool { - return h.dagFetcher.Overloaded() || h.dagProcessor.Overloaded() - }, - PeerEpoch: func(peer string) idx.Epoch { - p := h.peers.Peer(peer) - if p == nil || p.Useless() { - return 0 - } - return p.progress.Epoch - }, - }) - h.dagSeeder = dagstreamseeder.New(h.config.Protocol.DagStreamSeeder, dagstreamseeder.Callbacks{ - ForEachEvent: c.s.ForEachEventRLP, - }) - - h.bvProcessor = h.makeBvProcessor(c.checkers) - h.bvLeecher = bvstreamleecher.New(h.config.Protocol.BvStreamLeecher, bvstreamleecher.Callbacks{ - LowestBlockToDecide: func() (idx.Epoch, idx.Block) { - llrs := h.store.GetLlrState() - epoch := h.store.FindBlockEpoch(llrs.LowestBlockToDecide) - return epoch, llrs.LowestBlockToDecide - }, - MaxEpochToDecide: func() idx.Epoch { - if !h.syncStatus.RequestLLR() { - return 0 - } - return h.store.GetLlrState().LowestEpochToFill - }, - IsProcessed: h.store.HasBlockVotes, - RequestChunk: func(peer string, r bvstream.Request) error { - p := h.peers.Peer(peer) - if p == nil { - return errNotRegistered - } - return p.RequestBVsStream(r) - }, - Suspend: func(_ string) bool { - return h.bvProcessor.Overloaded() - }, - PeerBlock: func(peer string) idx.Block { - p := h.peers.Peer(peer) - if p == nil || p.Useless() { - return 0 - } - return p.progress.LastBlockIdx - }, - }) - h.bvSeeder = bvstreamseeder.New(h.config.Protocol.BvStreamSeeder, bvstreamseeder.Callbacks{ - Iterate: h.store.IterateOverlappingBlockVotesRLP, - }) - - h.brProcessor = h.makeBrProcessor() - h.brLeecher = brstreamleecher.New(h.config.Protocol.BrStreamLeecher, brstreamleecher.Callbacks{ - LowestBlockToFill: func() idx.Block { - return h.store.GetLlrState().LowestBlockToFill - }, - MaxBlockToFill: func() idx.Block { - if !h.syncStatus.RequestLLR() { - return 0 - } - // rough estimation for the max fill-able block - llrs := h.store.GetLlrState() - start := llrs.LowestBlockToFill - end := llrs.LowestBlockToDecide - if end > start+100 && h.store.HasBlock(start+100) { - return start + 100 - } - return end - }, - IsProcessed: h.store.HasBlock, - RequestChunk: func(peer string, r brstream.Request) error { - p := h.peers.Peer(peer) - if p == nil { - return errNotRegistered - } - return p.RequestBRsStream(r) - }, - Suspend: func(_ string) bool { - return h.brProcessor.Overloaded() - }, - PeerBlock: func(peer string) idx.Block { - p := h.peers.Peer(peer) - if p == nil || p.Useless() { - return 0 - } - return p.progress.LastBlockIdx - }, - }) - h.brSeeder = brstreamseeder.New(h.config.Protocol.BrStreamSeeder, brstreamseeder.Callbacks{ - Iterate: h.store.IterateFullBlockRecordsRLP, - }) - - h.epProcessor = h.makeEpProcessor(h.checkers) - h.epLeecher = epstreamleecher.New(h.config.Protocol.EpStreamLeecher, epstreamleecher.Callbacks{ - LowestEpochToFetch: func() idx.Epoch { - llrs := h.store.GetLlrState() - if llrs.LowestEpochToFill < llrs.LowestEpochToDecide { - return llrs.LowestEpochToFill - } - return llrs.LowestEpochToDecide - }, - MaxEpochToFetch: func() idx.Epoch { - if !h.syncStatus.RequestLLR() { - return 0 - } - return h.store.GetLlrState().LowestEpochToDecide + 10000 - }, - IsProcessed: h.store.HasHistoryBlockEpochState, - RequestChunk: func(peer string, r epstream.Request) error { - p := h.peers.Peer(peer) - if p == nil { - return errNotRegistered - } - return p.RequestEPsStream(r) - }, - Suspend: func(_ string) bool { - return h.epProcessor.Overloaded() - }, - PeerEpoch: func(peer string) idx.Epoch { - p := h.peers.Peer(peer) - if p == nil || p.Useless() { - return 0 - } - return p.progress.Epoch - }, - }) - h.epSeeder = epstreamseeder.New(h.config.Protocol.EpStreamSeeder, epstreamseeder.Callbacks{ - Iterate: h.store.IterateEpochPacksRLP, - }) - - return h, nil -} - -func (h *handler) peerMisbehaviour(peer string, err error) bool { - if eventcheck.IsBan(err) { - log.Warn("Dropping peer due to a misbehaviour", "peer", peer, "err", err) - h.removePeer(peer) - return true - } - return false -} - -func (h *handler) makeDagProcessor(checkers *eventcheck.Checkers) *dagprocessor.Processor { - // checkers - lightCheck := func(e dag.Event) error { - if h.store.GetEpoch() != e.ID().Epoch() { - return epochcheck.ErrNotRelevant - } - if h.dagProcessor.IsBuffered(e.ID()) { - return eventcheck.ErrDuplicateEvent - } - if h.store.HasEvent(e.ID()) { - return eventcheck.ErrAlreadyConnectedEvent - } - if err := checkers.Basiccheck.Validate(e.(inter.EventPayloadI)); err != nil { - return err - } - if err := checkers.Epochcheck.Validate(e.(inter.EventPayloadI)); err != nil { - return err - } - return nil - } - bufferedCheck := func(_e dag.Event, _parents dag.Events) error { - e := _e.(inter.EventI) - parents := make(inter.EventIs, len(_parents)) - for i := range _parents { - parents[i] = _parents[i].(inter.EventI) - } - var selfParent inter.EventI - if e.SelfParent() != nil { - selfParent = parents[0].(inter.EventI) - } - if err := checkers.Parentscheck.Validate(e, parents); err != nil { - return err - } - if err := checkers.Gaspowercheck.Validate(e, selfParent); err != nil { - return err - } - return nil - } - parentlessChecker := parentlesscheck.Checker{ - HeavyCheck: &heavycheck.EventsOnly{Checker: checkers.Heavycheck}, - LightCheck: lightCheck, - } - newProcessor := dagprocessor.New(datasemaphore.New(h.config.Protocol.EventsSemaphoreLimit, getSemaphoreWarningFn("DAG events")), h.config.Protocol.DagProcessor, dagprocessor.Callback{ - // DAG callbacks - Event: dagprocessor.EventCallback{ - Process: func(_e dag.Event) error { - e := _e.(*inter.EventPayload) - preStart := time.Now() - h.engineMu.Lock() - defer h.engineMu.Unlock() - - err := h.process.Event(e) - if err != nil { - return err - } - - // event is connected, announce it - passedSinceEvent := preStart.Sub(e.CreationTime().Time()) - h.BroadcastEvent(e, passedSinceEvent) - - return nil - }, - Released: func(e dag.Event, peer string, err error) { - if eventcheck.IsBan(err) { - log.Warn("Incoming event rejected", "event", e.ID().String(), "creator", e.Creator(), "err", err) - h.removePeer(peer) - } - }, - - Exists: func(id hash.Event) bool { - return h.store.HasEvent(id) - }, - - Get: func(id hash.Event) dag.Event { - e := h.store.GetEventPayload(id) - if e == nil { - return nil - } - return e - }, - - CheckParents: bufferedCheck, - CheckParentless: parentlessChecker.Enqueue, - }, - HighestLamport: h.store.GetHighestLamport, - }) - - return newProcessor -} - -func (h *handler) makeBvProcessor(checkers *eventcheck.Checkers) *bvprocessor.Processor { - // checkers - lightCheck := func(bvs inter.LlrSignedBlockVotes) error { - if h.store.HasBlockVotes(bvs.Val.Epoch, bvs.Val.LastBlock(), bvs.Signed.Locator.ID()) { - return eventcheck.ErrAlreadyProcessedBVs - } - return checkers.Basiccheck.ValidateBVs(bvs) - } - allChecker := bvallcheck.Checker{ - HeavyCheck: &heavycheck.BVsOnly{Checker: checkers.Heavycheck}, - LightCheck: lightCheck, - } - return bvprocessor.New(datasemaphore.New(h.config.Protocol.BVsSemaphoreLimit, getSemaphoreWarningFn("BVs")), h.config.Protocol.BvProcessor, bvprocessor.Callback{ - // DAG callbacks - Item: bvprocessor.ItemCallback{ - Process: h.process.BVs, - Released: func(bvs inter.LlrSignedBlockVotes, peer string, err error) { - if eventcheck.IsBan(err) { - log.Warn("Incoming BVs rejected", "BVs", bvs.Signed.Locator.ID(), "creator", bvs.Signed.Locator.Creator, "err", err) - h.removePeer(peer) - } - }, - Check: allChecker.Enqueue, - }, - }) -} - -func (h *handler) makeBrProcessor() *brprocessor.Processor { - // checkers - return brprocessor.New(datasemaphore.New(h.config.Protocol.BVsSemaphoreLimit, getSemaphoreWarningFn("BR")), h.config.Protocol.BrProcessor, brprocessor.Callback{ - // DAG callbacks - Item: brprocessor.ItemCallback{ - Process: h.process.BR, - Released: func(br ibr.LlrIdxFullBlockRecord, peer string, err error) { - if eventcheck.IsBan(err) { - log.Warn("Incoming BR rejected", "block", br.Idx, "err", err) - h.removePeer(peer) - } - }, - }, - }) -} - -func (h *handler) makeEpProcessor(checkers *eventcheck.Checkers) *epprocessor.Processor { - // checkers - lightCheck := func(ev inter.LlrSignedEpochVote) error { - if h.store.HasEpochVote(ev.Val.Epoch, ev.Signed.Locator.ID()) { - return eventcheck.ErrAlreadyProcessedEV - } - return checkers.Basiccheck.ValidateEV(ev) - } - allChecker := evallcheck.Checker{ - HeavyCheck: &heavycheck.EVOnly{Checker: checkers.Heavycheck}, - LightCheck: lightCheck, - } - // checkers - return epprocessor.New(datasemaphore.New(h.config.Protocol.BVsSemaphoreLimit, getSemaphoreWarningFn("BR")), h.config.Protocol.EpProcessor, epprocessor.Callback{ - // DAG callbacks - Item: epprocessor.ItemCallback{ - ProcessEV: h.process.EV, - ProcessER: h.process.ER, - ReleasedEV: func(ev inter.LlrSignedEpochVote, peer string, err error) { - if eventcheck.IsBan(err) { - log.Warn("Incoming EV rejected", "event", ev.Signed.Locator.ID(), "creator", ev.Signed.Locator.Creator, "err", err) - h.removePeer(peer) - } - }, - ReleasedER: func(er ier.LlrIdxFullEpochRecord, peer string, err error) { - if eventcheck.IsBan(err) { - log.Warn("Incoming ER rejected", "epoch", er.Idx, "err", err) - h.removePeer(peer) - } - }, - CheckEV: allChecker.Enqueue, - }, - }) -} - -func (h *handler) isEventInterested(id hash.Event, epoch idx.Epoch) bool { - if id.Epoch() != epoch { - return false - } - - if h.dagProcessor.IsBuffered(id) || h.store.HasEvent(id) { - return false - } - return true -} - -func (h *handler) onlyInterestedEventsI(ids []interface{}) []interface{} { - if len(ids) == 0 { - return ids - } - epoch := h.store.GetEpoch() - interested := make([]interface{}, 0, len(ids)) - for _, id := range ids { - if h.isEventInterested(id.(hash.Event), epoch) { - interested = append(interested, id) - } - } - return interested -} - -func (h *handler) removePeer(id string) { - peer := h.peers.Peer(id) - if peer != nil { - peer.Peer.Disconnect(p2p.DiscUselessPeer) - } -} - -func (h *handler) unregisterPeer(id string) { - // Short circuit if the peer was already removed - peer := h.peers.Peer(id) - if peer == nil { - return - } - log.Debug("Removing peer", "peer", id) - - // Unregister the peer from the leecher's and seeder's and peer sets - _ = h.epLeecher.UnregisterPeer(id) - _ = h.epSeeder.UnregisterPeer(id) - _ = h.dagLeecher.UnregisterPeer(id) - _ = h.dagSeeder.UnregisterPeer(id) - _ = h.brLeecher.UnregisterPeer(id) - _ = h.brSeeder.UnregisterPeer(id) - _ = h.bvLeecher.UnregisterPeer(id) - _ = h.bvSeeder.UnregisterPeer(id) - // Remove the `snap` extension if it exists - if peer.snapExt != nil { - _ = h.snapLeecher.SnapSyncer.Unregister(id) - } - if err := h.peers.UnregisterPeer(id); err != nil { - log.Error("Peer removal failed", "peer", id, "err", err) - } -} - -func (h *handler) Start(maxPeers int) { - h.snapsyncStageTick() - - h.maxPeers = maxPeers - - // broadcast transactions - h.txsCh = make(chan evmcore.NewTxsNotify, txChanSize) - h.txsSub = h.txpool.SubscribeNewTxsNotify(h.txsCh) - - h.loopsWg.Add(1) - go h.txBroadcastLoop() - - if h.notifier != nil { - // broadcast mined events - h.emittedEventsCh = make(chan *inter.EventPayload, 4) - h.emittedEventsSub = h.notifier.SubscribeNewEmitted(h.emittedEventsCh) - // epoch changes - h.newEpochsCh = make(chan idx.Epoch, 4) - h.newEpochsSub = h.notifier.SubscribeNewEpoch(h.newEpochsCh) - - h.loopsWg.Add(3) - go h.emittedBroadcastLoop() - go h.progressBroadcastLoop() - go h.onNewEpochLoop() - } - - // start sync handlers - go h.txsyncLoop() - h.loopsWg.Add(2) - go h.snapsyncStateLoop() - go h.snapsyncStageLoop() - h.dagFetcher.Start() - h.txFetcher.Start() - h.checkers.Heavycheck.Start() - - h.epProcessor.Start() - h.epSeeder.Start() - h.epLeecher.Start() - - h.dagProcessor.Start() - h.dagSeeder.Start() - h.dagLeecher.Start() - - h.bvProcessor.Start() - h.bvSeeder.Start() - h.bvLeecher.Start() - - h.brProcessor.Start() - h.brSeeder.Start() - h.brLeecher.Start() - h.started.Done() -} - -func (h *handler) Stop() { - log.Info("Stopping X1 protocol") - - h.brLeecher.Stop() - h.brSeeder.Stop() - h.brProcessor.Stop() - - h.bvLeecher.Stop() - h.bvSeeder.Stop() - h.bvProcessor.Stop() - - h.dagLeecher.Stop() - h.dagSeeder.Stop() - h.dagProcessor.Stop() - - h.epLeecher.Stop() - h.epSeeder.Stop() - h.epProcessor.Stop() - - h.checkers.Heavycheck.Stop() - h.txFetcher.Stop() - h.dagFetcher.Stop() - - close(h.quitProgressBradcast) - close(h.snapState.quit) - h.txsSub.Unsubscribe() // quits txBroadcastLoop - if h.notifier != nil { - h.emittedEventsSub.Unsubscribe() // quits eventBroadcastLoop - h.newEpochsSub.Unsubscribe() // quits onNewEpochLoop - } - - // Wait for the subscription loops to come down. - h.loopsWg.Wait() - - h.msgSemaphore.Terminate() - // Quit the sync loop. - // After this send has completed, no new peers will be accepted. - close(h.quitSync) - - // Disconnect existing sessions. - // This also closes the gate for any new registrations on the peer set. - // sessions which are already established but not added to h.peers yet - // will exit when they try to register. - h.peers.Close() - - // Wait for all peer handler goroutines to come down. - h.wg.Wait() - h.peerWG.Wait() - - log.Info("X1 protocol stopped") -} - -func (h *handler) myProgress() PeerProgress { - bs := h.store.GetBlockState() - epoch := h.store.GetEpoch() - return PeerProgress{ - Epoch: epoch, - LastBlockIdx: bs.LastBlock.Idx, - LastBlockAtropos: bs.LastBlock.Atropos, - } -} - -func (h *handler) highestPeerProgress() PeerProgress { - peers := h.peers.List() - max := h.myProgress() - for _, peer := range peers { - if max.LastBlockIdx < peer.progress.LastBlockIdx { - max = peer.progress - } - } - return max -} - -// handle is the callback invoked to manage the life cycle of a peer. When -// this function terminates, the peer is disconnected. -func (h *handler) handle(p *peer) error { - // If the peer has a `snap` extension, wait for it to connect so we can have - // a uniform initialization/teardown mechanism - snap, err := h.peers.WaitSnapExtension(p) - if err != nil { - p.Log().Error("Snapshot extension barrier failed", "err", err) - return err - } - useless := discfilter.Banned(p.Node().ID(), p.Node().Record()) - if !useless && (!eligibleForSnap(p.Peer) || !strings.Contains(strings.ToLower(p.Name()), "opera")) { - useless = true - discfilter.Ban(p.ID()) - } - if !p.Peer.Info().Network.Trusted && useless { - if h.peers.UselessNum() >= h.maxPeers/10 { - // don't allow more than 10% of useless peers - return p2p.DiscTooManyPeers - } - p.SetUseless() - } - - h.peerWG.Add(1) - defer h.peerWG.Done() - - // Execute the handshake - var ( - genesis = *h.store.GetGenesisID() - myProgress = h.myProgress() - ) - if err := p.Handshake(h.NetworkID, myProgress, common.Hash(genesis)); err != nil { - p.Log().Debug("Handshake failed", "err", err) - if !useless { - discfilter.Ban(p.ID()) - } - return err - } - - // Ignore maxPeers if this is a trusted peer - if h.peers.Len() >= h.maxPeers && !p.Peer.Info().Network.Trusted { - return p2p.DiscTooManyPeers - } - p.Log().Debug("Peer connected", "name", p.Name()) - - // Register the peer locally - if err := h.peers.RegisterPeer(p, snap); err != nil { - p.Log().Warn("Peer registration failed", "err", err) - return err - } - if err := h.dagLeecher.RegisterPeer(p.id); err != nil { - p.Log().Warn("Leecher peer registration failed", "err", err) - return err - } - if p.RunningCap(ProtocolName, []uint{FTM63}) { - if err := h.epLeecher.RegisterPeer(p.id); err != nil { - p.Log().Warn("Leecher peer registration failed", "err", err) - return err - } - if err := h.bvLeecher.RegisterPeer(p.id); err != nil { - p.Log().Warn("Leecher peer registration failed", "err", err) - return err - } - if err := h.brLeecher.RegisterPeer(p.id); err != nil { - p.Log().Warn("Leecher peer registration failed", "err", err) - return err - } - } - if snap != nil { - if err := h.snapLeecher.SnapSyncer.Register(snap); err != nil { - p.Log().Error("Failed to register peer in snap syncer", "err", err) - return err - } - } - defer h.unregisterPeer(p.id) - - // Propagate existing transactions. new transactions appearing - // after this will be sent via broadcasts. - h.syncTransactions(p, h.txpool.SampleHashes(h.config.Protocol.MaxInitialTxHashesSend)) - - // Handle incoming messages until the connection is torn down - for { - if err := h.handleMsg(p); err != nil { - p.Log().Debug("Message handling failed", "err", err) - return err - } - } -} - -func interfacesToEventIDs(ids []interface{}) hash.Events { - res := make(hash.Events, len(ids)) - for i, id := range ids { - res[i] = id.(hash.Event) - } - return res -} - -func eventIDsToInterfaces(ids hash.Events) []interface{} { - res := make([]interface{}, len(ids)) - for i, id := range ids { - res[i] = id - } - return res -} - -func interfacesToTxids(ids []interface{}) []common.Hash { - res := make([]common.Hash, len(ids)) - for i, id := range ids { - res[i] = id.(common.Hash) - } - return res -} - -func txidsToInterfaces(ids []common.Hash) []interface{} { - res := make([]interface{}, len(ids)) - for i, id := range ids { - res[i] = id - } - return res -} - -func (h *handler) handleTxHashes(p *peer, announces []common.Hash) { - // Mark the hashes as present at the remote node - now := time.Now() - for _, id := range announces { - txtime.Saw(id, now) - p.MarkTransaction(id) - } - // Schedule all the unknown hashes for retrieval - requestTransactions := func(ids []interface{}) error { - return p.RequestTransactions(interfacesToTxids(ids)) - } - _ = h.txFetcher.NotifyAnnounces(p.id, txidsToInterfaces(announces), time.Now(), requestTransactions) -} - -func (h *handler) handleTxs(p *peer, txs types.Transactions) { - // Mark the hashes as present at the remote node - now := time.Now() - for _, tx := range txs { - txid := tx.Hash() - txtime.Saw(txid, now) - p.MarkTransaction(txid) - } - h.txpool.AddRemotes(txs) -} - -func (h *handler) handleEventHashes(p *peer, announces hash.Events) { - // Mark the hashes as present at the remote node - for _, id := range announces { - p.MarkEvent(id) - } - // filter too high IDs - notTooHigh := make(hash.Events, 0, len(announces)) - sessionCfg := h.config.Protocol.DagStreamLeecher.Session - for _, id := range announces { - maxLamport := h.store.GetHighestLamport() + idx.Lamport(sessionCfg.DefaultChunkItemsNum+1)*idx.Lamport(sessionCfg.ParallelChunksDownload) - if id.Lamport() <= maxLamport { - notTooHigh = append(notTooHigh, id) - } - } - if len(announces) != len(notTooHigh) { - h.dagLeecher.ForceSyncing() - } - if len(notTooHigh) == 0 { - return - } - // Schedule all the unknown hashes for retrieval - requestEvents := func(ids []interface{}) error { - return p.RequestEvents(interfacesToEventIDs(ids)) - } - _ = h.dagFetcher.NotifyAnnounces(p.id, eventIDsToInterfaces(notTooHigh), time.Now(), requestEvents) -} - -func (h *handler) handleEvents(p *peer, events dag.Events, ordered bool) { - // Mark the hashes as present at the remote node - now := time.Now() - for _, e := range events { - for _, tx := range e.(inter.EventPayloadI).Txs() { - txtime.Saw(tx.Hash(), now) - } - p.MarkEvent(e.ID()) - } - // filter too high events - notTooHigh := make(dag.Events, 0, len(events)) - sessionCfg := h.config.Protocol.DagStreamLeecher.Session - for _, e := range events { - maxLamport := h.store.GetHighestLamport() + idx.Lamport(sessionCfg.DefaultChunkItemsNum+1)*idx.Lamport(sessionCfg.ParallelChunksDownload) - if e.Lamport() <= maxLamport { - notTooHigh = append(notTooHigh, e) - } - if now.Sub(e.(inter.EventI).CreationTime().Time()) < 10*time.Minute { - h.syncStatus.MarkMaybeSynced() - } - } - if len(events) != len(notTooHigh) { - h.dagLeecher.ForceSyncing() - } - if len(notTooHigh) == 0 { - return - } - // Schedule all the events for connection - peer := *p - requestEvents := func(ids []interface{}) error { - return peer.RequestEvents(interfacesToEventIDs(ids)) - } - notifyAnnounces := func(ids hash.Events) { - _ = h.dagFetcher.NotifyAnnounces(peer.id, eventIDsToInterfaces(ids), now, requestEvents) - } - _ = h.dagProcessor.Enqueue(peer.id, notTooHigh, ordered, notifyAnnounces, nil) -} - -// handleMsg is invoked whenever an inbound message is received from a remote -// peer. The remote connection is torn down upon returning any error. -func (h *handler) handleMsg(p *peer) error { - // Read the next message from the remote peer, and ensure it's fully consumed - msg, err := p.rw.ReadMsg() - if err != nil { - return err - } - if msg.Size > protocolMaxMsgSize { - return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, protocolMaxMsgSize) - } - defer msg.Discard() - // Acquire semaphore for serialized messages - eventsSizeEst := dag.Metric{ - Num: 1, - Size: uint64(msg.Size), - } - if !h.msgSemaphore.Acquire(eventsSizeEst, h.config.Protocol.MsgsSemaphoreTimeout) { - h.Log.Warn("Failed to acquire semaphore for p2p message", "size", msg.Size, "peer", p.id) - return nil - } - defer h.msgSemaphore.Release(eventsSizeEst) - - // Handle the message depending on its contents - switch { - case msg.Code == HandshakeMsg: - // Status messages should never arrive after the handshake - return errResp(ErrExtraStatusMsg, "uncontrolled status message") - - case msg.Code == ProgressMsg: - var progress PeerProgress - if err := msg.Decode(&progress); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - p.SetProgress(progress) - - case msg.Code == EvmTxsMsg: - // Transactions arrived, make sure we have a valid and fresh graph to handle them - if !h.syncStatus.AcceptTxs() { - break - } - // Transactions can be processed, parse all of them and deliver to the pool - var txs types.Transactions - if err := msg.Decode(&txs); err != nil { - return errResp(ErrDecode, "msg %v: %v", msg, err) - } - if err := checkLenLimits(len(txs), txs); err != nil { - return err - } - txids := make([]interface{}, txs.Len()) - for i, tx := range txs { - txids[i] = tx.Hash() - } - _ = h.txFetcher.NotifyReceived(txids) - h.handleTxs(p, txs) - - case msg.Code == NewEvmTxHashesMsg: - // Transactions arrived, make sure we have a valid and fresh graph to handle them - if !h.syncStatus.AcceptTxs() { - break - } - // Transactions can be processed, parse all of them and deliver to the pool - var txHashes []common.Hash - if err := msg.Decode(&txHashes); err != nil { - return errResp(ErrDecode, "msg %v: %v", msg, err) - } - if err := checkLenLimits(len(txHashes), txHashes); err != nil { - return err - } - h.handleTxHashes(p, txHashes) - - case msg.Code == GetEvmTxsMsg: - var requests []common.Hash - if err := msg.Decode(&requests); err != nil { - return errResp(ErrDecode, "msg %v: %v", msg, err) - } - if err := checkLenLimits(len(requests), requests); err != nil { - return err - } - - txs := make(types.Transactions, 0, len(requests)) - for _, txid := range requests { - tx := h.txpool.Get(txid) - if tx == nil { - continue - } - txs = append(txs, tx) - } - SplitTransactions(txs, func(batch types.Transactions) { - p.EnqueueSendTransactions(batch, p.queue) - }) - - case msg.Code == EventsMsg: - if !h.syncStatus.AcceptEvents() { - break - } - - var events inter.EventPayloads - if err := msg.Decode(&events); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if err := checkLenLimits(len(events), events); err != nil { - return err - } - _ = h.dagFetcher.NotifyReceived(eventIDsToInterfaces(events.IDs())) - h.handleEvents(p, events.Bases(), events.Len() > 1) - - case msg.Code == NewEventIDsMsg: - // Fresh events arrived, make sure we have a valid and fresh graph to handle them - if !h.syncStatus.AcceptEvents() { - break - } - var announces hash.Events - if err := msg.Decode(&announces); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if err := checkLenLimits(len(announces), announces); err != nil { - return err - } - h.handleEventHashes(p, announces) - - case msg.Code == GetEventsMsg: - var requests hash.Events - if err := msg.Decode(&requests); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if err := checkLenLimits(len(requests), requests); err != nil { - return err - } - - rawEvents := make([]rlp.RawValue, 0, len(requests)) - ids := make(hash.Events, 0, len(requests)) - size := 0 - for _, id := range requests { - if raw := h.store.GetEventPayloadRLP(id); raw != nil { - rawEvents = append(rawEvents, raw) - ids = append(ids, id) - size += len(raw) - } else { - h.Log.Debug("requested event not found", "hash", id) - } - if size >= softResponseLimitSize { - break - } - } - if len(rawEvents) != 0 { - p.EnqueueSendEventsRLP(rawEvents, ids, p.queue) - } - - case msg.Code == RequestEventsStream: - var request dagstream.Request - if err := msg.Decode(&request); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if request.Limit.Num > hardLimitItems-1 { - return errResp(ErrMsgTooLarge, "%v", msg) - } - if request.Limit.Size > protocolMaxMsgSize*2/3 { - return errResp(ErrMsgTooLarge, "%v", msg) - } - - pid := p.id - _, peerErr := h.dagSeeder.NotifyRequestReceived(dagstreamseeder.Peer{ - ID: pid, - SendChunk: p.SendEventsStream, - Misbehaviour: func(err error) { - h.peerMisbehaviour(pid, err) - }, - }, request) - if peerErr != nil { - return peerErr - } - - case msg.Code == EventsStreamResponse: - if !h.syncStatus.AcceptEvents() { - break - } - - var chunk dagChunk - if err := msg.Decode(&chunk); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if err := checkLenLimits(len(chunk.Events)+len(chunk.IDs)+1, chunk); err != nil { - return err - } - - if (len(chunk.Events) != 0) && (len(chunk.IDs) != 0) { - return errors.New("expected either events or event hashes") - } - var last hash.Event - if len(chunk.IDs) != 0 { - h.handleEventHashes(p, chunk.IDs) - last = chunk.IDs[len(chunk.IDs)-1] - } - if len(chunk.Events) != 0 { - h.handleEvents(p, chunk.Events.Bases(), true) - last = chunk.Events[len(chunk.Events)-1].ID() - } - - _ = h.dagLeecher.NotifyChunkReceived(chunk.SessionID, last, chunk.Done) - - case msg.Code == RequestBVsStream: - var request bvstream.Request - if err := msg.Decode(&request); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if request.Limit.Num > hardLimitItems-1 { - return errResp(ErrMsgTooLarge, "%v", msg) - } - if request.Limit.Size > protocolMaxMsgSize*2/3 { - return errResp(ErrMsgTooLarge, "%v", msg) - } - - pid := p.id - _, peerErr := h.bvSeeder.NotifyRequestReceived(bvstreamseeder.Peer{ - ID: pid, - SendChunk: p.SendBVsStream, - Misbehaviour: func(err error) { - h.peerMisbehaviour(pid, err) - }, - }, request) - if peerErr != nil { - return peerErr - } - - case msg.Code == BVsStreamResponse: - var chunk bvsChunk - if err := msg.Decode(&chunk); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if err := checkLenLimits(len(chunk.BVs)+1, chunk); err != nil { - return err - } - - var last bvstreamleecher.BVsID - if len(chunk.BVs) != 0 { - _ = h.bvProcessor.Enqueue(p.id, chunk.BVs, nil) - last = bvstreamleecher.BVsID{ - Epoch: chunk.BVs[len(chunk.BVs)-1].Val.Epoch, - LastBlock: chunk.BVs[len(chunk.BVs)-1].Val.LastBlock(), - ID: chunk.BVs[len(chunk.BVs)-1].Signed.Locator.ID(), - } - } - - _ = h.bvLeecher.NotifyChunkReceived(chunk.SessionID, last, chunk.Done) - - case msg.Code == RequestBRsStream: - var request brstream.Request - if err := msg.Decode(&request); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if request.Limit.Num > hardLimitItems-1 { - return errResp(ErrMsgTooLarge, "%v", msg) - } - if request.Limit.Size > protocolMaxMsgSize*2/3 { - return errResp(ErrMsgTooLarge, "%v", msg) - } - - pid := p.id - _, peerErr := h.brSeeder.NotifyRequestReceived(brstreamseeder.Peer{ - ID: pid, - SendChunk: p.SendBRsStream, - Misbehaviour: func(err error) { - h.peerMisbehaviour(pid, err) - }, - }, request) - if peerErr != nil { - return peerErr - } - - case msg.Code == BRsStreamResponse: - if !h.syncStatus.AcceptBlockRecords() { - break - } - - msgSize := uint64(msg.Size) - var chunk brsChunk - if err := msg.Decode(&chunk); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if err := checkLenLimits(len(chunk.BRs)+1, chunk); err != nil { - return err - } - - var last idx.Block - if len(chunk.BRs) != 0 { - _ = h.brProcessor.Enqueue(p.id, chunk.BRs, msgSize, nil) - last = chunk.BRs[len(chunk.BRs)-1].Idx - } - - _ = h.brLeecher.NotifyChunkReceived(chunk.SessionID, last, chunk.Done) - - case msg.Code == RequestEPsStream: - var request epstream.Request - if err := msg.Decode(&request); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if request.Limit.Num > hardLimitItems-1 { - return errResp(ErrMsgTooLarge, "%v", msg) - } - if request.Limit.Size > protocolMaxMsgSize*2/3 { - return errResp(ErrMsgTooLarge, "%v", msg) - } - - pid := p.id - _, peerErr := h.epSeeder.NotifyRequestReceived(epstreamseeder.Peer{ - ID: pid, - SendChunk: p.SendEPsStream, - Misbehaviour: func(err error) { - h.peerMisbehaviour(pid, err) - }, - }, request) - if peerErr != nil { - return peerErr - } - - case msg.Code == EPsStreamResponse: - msgSize := uint64(msg.Size) - var chunk epsChunk - if err := msg.Decode(&chunk); err != nil { - return errResp(ErrDecode, "%v: %v", msg, err) - } - if err := checkLenLimits(len(chunk.EPs)+1, chunk); err != nil { - return err - } - - var last idx.Epoch - if len(chunk.EPs) != 0 { - _ = h.epProcessor.Enqueue(p.id, chunk.EPs, msgSize, nil) - last = chunk.EPs[len(chunk.EPs)-1].Record.Idx - } - - _ = h.epLeecher.NotifyChunkReceived(chunk.SessionID, last, chunk.Done) - - default: - return errResp(ErrInvalidMsgCode, "%v", msg.Code) - } - return nil -} - -func (h *handler) decideBroadcastAggressiveness(size int, passed time.Duration, peersNum int) int { - percents := 100 - maxPercents := 1000000 * percents - latencyVsThroughputTradeoff := maxPercents - cfg := h.config.Protocol - if cfg.ThroughputImportance != 0 { - latencyVsThroughputTradeoff = (cfg.LatencyImportance * percents) / cfg.ThroughputImportance - } - - broadcastCost := passed * time.Duration(128+size) / 128 - broadcastAllCostTarget := time.Duration(latencyVsThroughputTradeoff) * (700 * time.Millisecond) / time.Duration(percents) - broadcastSqrtCostTarget := broadcastAllCostTarget * 10 - - fullRecipients := 0 - if latencyVsThroughputTradeoff >= maxPercents { - // edge case - fullRecipients = peersNum - } else if latencyVsThroughputTradeoff <= 0 { - // edge case - fullRecipients = 0 - } else if broadcastCost <= broadcastAllCostTarget { - // if event is small or was created recently, always send to everyone full event - fullRecipients = peersNum - } else if broadcastCost <= broadcastSqrtCostTarget || passed == 0 { - // if event is big but was created recently, send full event to subset of peers - fullRecipients = int(math.Sqrt(float64(peersNum))) - if fullRecipients < 4 { - fullRecipients = 4 - } - } - if fullRecipients > peersNum { - fullRecipients = peersNum - } - return fullRecipients -} - -// BroadcastEvent will either propagate a event to a subset of it's peers, or -// will only announce it's availability (depending what's requested). -func (h *handler) BroadcastEvent(event *inter.EventPayload, passed time.Duration) int { - if passed < 0 { - passed = 0 - } - id := event.ID() - peers := h.peers.PeersWithoutEvent(id) - if len(peers) == 0 { - log.Trace("Event is already known to all peers", "hash", id) - return 0 - } - - fullRecipients := h.decideBroadcastAggressiveness(event.Size(), passed, len(peers)) - - // Exclude low quality peers from fullBroadcast - var fullBroadcast = make([]*peer, 0, fullRecipients) - var hashBroadcast = make([]*peer, 0, len(peers)) - for _, p := range peers { - if !p.Useless() && len(fullBroadcast) < fullRecipients { - fullBroadcast = append(fullBroadcast, p) - } else { - hashBroadcast = append(hashBroadcast, p) - } - } - for _, peer := range fullBroadcast { - peer.AsyncSendEvents(inter.EventPayloads{event}, peer.queue) - } - // Broadcast of event hash to the rest peers - for _, peer := range hashBroadcast { - peer.AsyncSendEventIDs(hash.Events{event.ID()}, peer.queue) - } - log.Trace("Broadcast event", "hash", id, "fullRecipients", len(fullBroadcast), "hashRecipients", len(hashBroadcast)) - return len(peers) -} - -// BroadcastTxs will propagate a batch of transactions to all peers which are not known to -// already have the given transaction. -func (h *handler) BroadcastTxs(txs types.Transactions) { - var txset = make(map[*peer]types.Transactions) - - // Broadcast transactions to a batch of peers not knowing about it - totalSize := common.StorageSize(0) - for _, tx := range txs { - peers := h.peers.PeersWithoutTx(tx.Hash()) - for _, peer := range peers { - txset[peer] = append(txset[peer], tx) - } - totalSize += tx.Size() - log.Trace("Broadcast transaction", "hash", tx.Hash(), "recipients", len(peers)) - } - fullRecipients := h.decideBroadcastAggressiveness(int(totalSize), time.Second, len(txset)) - i := 0 - for peer, txs := range txset { - SplitTransactions(txs, func(batch types.Transactions) { - if i < fullRecipients { - peer.AsyncSendTransactions(batch, peer.queue) - } else { - txids := make([]common.Hash, batch.Len()) - for i, tx := range batch { - txids[i] = tx.Hash() - } - peer.AsyncSendTransactionHashes(txids, peer.queue) - } - }) - i++ - } -} - -// Mined broadcast loop -func (h *handler) emittedBroadcastLoop() { - defer h.loopsWg.Done() - for { - select { - case emitted := <-h.emittedEventsCh: - h.BroadcastEvent(emitted, 0) - // Err() channel will be closed when unsubscribing. - case <-h.emittedEventsSub.Err(): - return - } - } -} - -func (h *handler) broadcastProgress() { - progress := h.myProgress() - for _, peer := range h.peers.List() { - peer.AsyncSendProgress(progress, peer.queue) - } -} - -// Progress broadcast loop -func (h *handler) progressBroadcastLoop() { - ticker := time.NewTicker(h.config.Protocol.ProgressBroadcastPeriod) - defer ticker.Stop() - defer h.loopsWg.Done() - // automatically stops if unsubscribe - for { - select { - case <-ticker.C: - h.broadcastProgress() - case <-h.quitProgressBradcast: - return - } - } -} - -func (h *handler) onNewEpochLoop() { - defer h.loopsWg.Done() - for { - select { - case myEpoch := <-h.newEpochsCh: - h.dagProcessor.Clear() - h.dagLeecher.OnNewEpoch(myEpoch) - // Err() channel will be closed when unsubscribing. - case <-h.newEpochsSub.Err(): - return - } - } -} - -func (h *handler) txBroadcastLoop() { - ticker := time.NewTicker(h.config.Protocol.RandomTxHashesSendPeriod) - defer ticker.Stop() - defer h.loopsWg.Done() - for { - select { - case notify := <-h.txsCh: - h.BroadcastTxs(notify.Txs) - - // Err() channel will be closed when unsubscribing. - case <-h.txsSub.Err(): - return - - case <-ticker.C: - if !h.syncStatus.AcceptTxs() { - break - } - peers := h.peers.List() - if len(peers) == 0 { - continue - } - randPeer := peers[rand.Intn(len(peers))] - h.syncTransactions(randPeer, h.txpool.SampleHashes(h.config.Protocol.MaxRandomTxHashesSend)) - } - } -} - -// NodeInfo represents a short summary of the sub-protocol metadata -// known about the host peer. -type NodeInfo struct { - Network uint64 `json:"network"` // network ID - Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis object - Epoch idx.Epoch `json:"epoch"` - NumOfBlocks idx.Block `json:"blocks"` - //Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules -} - -// NodeInfo retrieves some protocol metadata about the running host node. -func (h *handler) NodeInfo() *NodeInfo { - numOfBlocks := h.store.GetLatestBlockIndex() - return &NodeInfo{ - Network: h.NetworkID, - Genesis: common.Hash(*h.store.GetGenesisID()), - Epoch: h.store.GetEpoch(), - NumOfBlocks: numOfBlocks, - } -} - -func getSemaphoreWarningFn(name string) func(dag.Metric, dag.Metric, dag.Metric) { - return func(received dag.Metric, processing dag.Metric, releasing dag.Metric) { - log.Warn(fmt.Sprintf("%s semaphore inconsistency", name), - "receivedNum", received.Num, "receivedSize", received.Size, - "processingNum", processing.Num, "processingSize", processing.Size, - "releasingNum", releasing.Num, "releasingSize", releasing.Size) - } -} diff --git a/evm/go-x1/gossip/handler_fuzz.go b/evm/go-x1/gossip/handler_fuzz.go deleted file mode 100644 index ede7690..0000000 --- a/evm/go-x1/gossip/handler_fuzz.go +++ /dev/null @@ -1,165 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package gossip - -import ( - "bytes" - "errors" - "math/rand" - "sync" - - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" - _ "github.com/dvyukov/go-fuzz/go-fuzz-defs" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/utils" - "github.com/Fantom-foundation/go-opera/utils/signers/gsignercache" -) - -const ( - fuzzHot int = 1 // if the fuzzer should increase priority of the given input during subsequent fuzzing; - fuzzCold int = -1 // if the input must not be added to corpus even if gives new coverage; - fuzzNoMatter int = 0 // otherwise. -) - -var ( - fuzzedHandler *handler -) - -func FuzzHandler(data []byte) int { - var err error - if fuzzedHandler == nil { - fuzzedHandler, err = makeFuzzedHandler() - if err != nil { - panic(err) - } - } - - msg, err := newFuzzMsg(data) - if err != nil { - return fuzzCold - } - input := &fuzzMsgReadWriter{msg} - other := &peer{ - version: ProtocolVersion, - Peer: p2p.NewPeer(randomID(), "fake-node-1", []p2p.Cap{}), - rw: input, - } - - err = fuzzedHandler.handleMsg(other) - if err != nil { - return fuzzNoMatter - } - - return fuzzHot -} - -func makeFuzzedHandler() (h *handler, err error) { - const ( - genesisStakers = 3 - genesisBalance = 1e18 - genesisStake = 2 * 4e6 - ) - - genStore := makefakegenesis.FakeGenesisStore(genesisStakers, utils.ToFtm(genesisBalance), utils.ToFtm(genesisStake)) - genesis := genStore.Genesis() - - config := DefaultConfig(cachescale.Identity) - store := NewMemStore() - _, err = store.ApplyGenesis(genesis) - if err != nil { - return - } - - var ( - network = opera.FakeNetRules() - heavyCheckReader HeavyCheckReader - gasPowerCheckReader GasPowerCheckReader - // TODO: init - ) - - mu := new(sync.RWMutex) - feed := new(ServiceFeed) - net := store.GetRules() - txSigner := gsignercache.Wrap(types.LatestSignerForChainID(net.EvmChainConfig().ChainID)) - checkers := makeCheckers(config.HeavyCheck, txSigner, &heavyCheckReader, &gasPowerCheckReader, store) - - txpool := evmcore.NewTxPool(evmcore.DefaultTxPoolConfig, network.EvmChainConfig(), &EvmStateReader{ - ServiceFeed: feed, - store: store, - }) - - h, err = newHandler( - handlerConfig{ - config: config, - notifier: feed, - txpool: txpool, - engineMu: mu, - checkers: checkers, - s: store, - process: processCallback{ - Event: func(event *inter.EventPayload) error { - return nil - }, - }, - }) - if err != nil { - return - } - - h.Start(3) - return -} - -func randomID() (id enode.ID) { - for i := range id { - id[i] = byte(rand.Intn(255)) - } - return id -} - -type fuzzMsgReadWriter struct { - msg *p2p.Msg -} - -func newFuzzMsg(data []byte) (*p2p.Msg, error) { - if len(data) < 1 { - return nil, errors.New("empty data") - } - - var ( - codes = []uint64{ - HandshakeMsg, - EvmTxsMsg, - ProgressMsg, - NewEventIDsMsg, - GetEventsMsg, - EventsMsg, - RequestEventsStream, - EventsStreamResponse, - } - code = codes[int(data[0])%len(codes)] - ) - data = data[1:] - - return &p2p.Msg{ - Code: code, - Size: uint32(len(data)), - Payload: bytes.NewReader(data), - }, nil -} - -func (rw *fuzzMsgReadWriter) ReadMsg() (p2p.Msg, error) { - return *rw.msg, nil -} - -func (rw *fuzzMsgReadWriter) WriteMsg(p2p.Msg) error { - return nil -} diff --git a/evm/go-x1/gossip/handler_snap.go b/evm/go-x1/gossip/handler_snap.go deleted file mode 100644 index dda20e8..0000000 --- a/evm/go-x1/gossip/handler_snap.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package gossip - -import ( - "github.com/ethereum/go-ethereum/eth/protocols/snap" - "github.com/ethereum/go-ethereum/p2p/enode" -) - -// snapHandler implements the snap.Backend interface to handle the various network -// packets that are sent as replies or broadcasts. -type snapHandler handler - -func (h *snapHandler) Chain() snap.BlockChain { - return h.chain -} - -// RunPeer is invoked when a peer joins on the `snap` protocol. -func (h *snapHandler) RunPeer(peer *snap.Peer, hand snap.Handler) error { - return (*handler)(h).runSnapExtension(peer, hand) -} - -// PeerInfo retrieves all known `snap` information about a peer. -func (h *snapHandler) PeerInfo(id enode.ID) interface{} { - if p := h.peers.Peer(id.String()); p != nil { - if p.snapExt != nil { - return p.snapExt.info() - } - } - return nil -} - -// Handle is invoked from a peer's message handler when it receives a new remote -// message that the handler couldn't consume and serve itself. -func (h *snapHandler) Handle(peer *snap.Peer, packet snap.Packet) error { - return h.snapLeecher.DeliverSnapPacket(peer, packet) -} - -// runSnapExtension registers a `snap` peer into the joint eth/snap peerset and -// starts handling inbound messages. As `snap` is only a satellite protocol to -// `eth`, all subsystem registrations and lifecycle management will be done by -// the main `eth` handler to prevent strange races. -func (h *handler) runSnapExtension(peer *snap.Peer, handler snap.Handler) error { - h.peerWG.Add(1) - defer h.peerWG.Done() - if err := h.peers.RegisterSnapExtension(peer); err != nil { - logger := peer.Log().Error - if err == errSnapWithoutOpera { - logger = peer.Log().Trace - } - logger("Snapshot extension registration failed", "err", err) - return err - } - return handler(peer) -} diff --git a/evm/go-x1/gossip/heavycheck_test.go b/evm/go-x1/gossip/heavycheck_test.go deleted file mode 100644 index 7c13494..0000000 --- a/evm/go-x1/gossip/heavycheck_test.go +++ /dev/null @@ -1,832 +0,0 @@ -package gossip - -import ( - "bytes" - "math" - "testing" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/suite" - - "github.com/Fantom-foundation/go-opera/eventcheck/epochcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/heavycheck" - "github.com/Fantom-foundation/go-opera/inter" -) - -type LLRHeavyCheckTestSuite struct { - suite.Suite - - env *testEnv - me *inter.MutableEventPayload - startEpoch idx.Epoch -} - -func (s *LLRHeavyCheckTestSuite) SetupSuite() { - s.T().Log("setting up test suite") - - const ( - validatorsNum = 10 - startEpoch = 1 - ) - - env := newTestEnv(startEpoch, validatorsNum) - - em := env.emitters[0] - e, err := em.EmitEvent() - s.Require().NoError(err) - s.Require().NotNil(e) - - s.env = env - s.me = mutableEventPayloadFromImmutable(e) - s.startEpoch = idx.Epoch(startEpoch) -} - -func (s *LLRHeavyCheckTestSuite) TearDownSuite() { - s.T().Log("tearing down test suite") - s.env.Close() -} - -func (s *LLRHeavyCheckTestSuite) TestHeavyCheckValidateEV() { - - var ev inter.LlrSignedEpochVote - - testCases := []struct { - name string - errExp error - pretest func() - }{ - { - "validateEV returns nil", - nil, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "validateEV returns ErrUnknownEpochEV", - heavycheck.ErrUnknownEpochEV, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch, - Vote: hash.HexToHash("0x01"), - }, - } - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "epochcheck.ErrAuth", - epochcheck.ErrAuth, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - } - - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(100) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "ErrWrongPayloadHash", - heavycheck.ErrWrongPayloadHash, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - } - - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(hash.Hash{}) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - }, - }, - - { - "ErrWrongEventSig", - heavycheck.ErrWrongEventSig, - func() { - ev = inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - } - - s.me.SetVersion(1) - s.me.SetEpochVote(ev.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(4) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - ev = inter.AsSignedEpochVote(s.me) - ev.Signed.Locator.Creator = 5 - }, - }, - } - - for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { - s.SetupSuite() - tc.pretest() - - err := s.env.checkers.Heavycheck.ValidateEV(ev) - - if tc.errExp != nil { - s.Require().Error(err) - s.Require().EqualError(err, tc.errExp.Error()) - } else { - s.Require().NoError(err) - } - }) - } - -} - -func (s *LLRHeavyCheckTestSuite) TestHeavyCheckValidateBVs() { - var bv inter.LlrSignedBlockVotes - - testCases := []struct { - name string - errExp error - pretest func() - }{ - { - "success", - nil, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetVersion(1) - s.me.SetBlockVotes(bv.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetCreator(2) - - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "ErrUnknownEpochBVs", - heavycheck.ErrUnknownEpochBVs, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: 25, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetVersion(1) - s.me.SetBlockVotes(bv.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(2) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "ErrImpossibleBVsEpoch", - heavycheck.ErrImpossibleBVsEpoch, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 0, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetVersion(1) - s.me.SetBlockVotes(bv.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(2) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "ErrUnknownEpochBVs", - heavycheck.ErrUnknownEpochBVs, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: 0, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - s.me.SetVersion(1) - s.me.SetBlockVotes(bv.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "epochcheck.ErrAuth", - epochcheck.ErrAuth, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - invalidValidatorID := idx.ValidatorID(100) - - s.me.SetVersion(1) - s.me.SetBlockVotes(bv.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(invalidValidatorID) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "ErrWrongPayloadHash", - heavycheck.ErrWrongPayloadHash, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - emptyPayload := hash.Hash{} - - s.me.SetVersion(1) - s.me.SetBlockVotes(bv.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(emptyPayload) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - { - "ErrWrongEventSig", - heavycheck.ErrWrongEventSig, - func() { - bv = inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetVersion(1) - s.me.SetBlockVotes(bv.Val) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(4) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - bv = inter.AsSignedBlockVotes(s.me) - bv.Signed.Locator.Creator = 5 - }, - }, - } - - for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { - s.SetupSuite() - tc.pretest() - - err := s.env.checkers.Heavycheck.ValidateBVs(bv) - - if tc.errExp != nil { - s.Require().Error(err) - s.Require().EqualError(err, tc.errExp.Error()) - } else { - s.Require().NoError(err) - } - }) - } -} - -func mutableEventPayloadFromImmutable(e *inter.EventPayload) *inter.MutableEventPayload { - me := &inter.MutableEventPayload{} - me.SetVersion(e.Version()) - me.SetNetForkID(e.NetForkID()) - me.SetCreator(e.Creator()) - me.SetEpoch(e.Epoch()) - me.SetCreationTime(e.CreationTime()) - me.SetMedianTime(e.MedianTime()) - me.SetPrevEpochHash(e.PrevEpochHash()) - me.SetExtra(e.Extra()) - me.SetGasPowerLeft(e.GasPowerLeft()) - me.SetGasPowerUsed(e.GasPowerUsed()) - me.SetPayloadHash(e.PayloadHash()) - me.SetSig(e.Sig()) - me.SetTxs(e.Txs()) - me.SetMisbehaviourProofs(e.MisbehaviourProofs()) - me.SetBlockVotes(e.BlockVotes()) - me.SetEpochVote(e.EpochVote()) - return me -} - -func (s *LLRHeavyCheckTestSuite) TestHeavyCheckValidateEvent() { - - testCases := []struct { - name string - errExp error - pretest func() - }{ - { - "success", - nil, - func() { - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetCreator(3) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - }, - }, - { - "epochcheck.ErrNotRelevant", - epochcheck.ErrNotRelevant, - func() { - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch + 1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - }, - }, - { - "epochcheck.ErrAuth", - epochcheck.ErrAuth, - func() { - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - invalidCreator := idx.ValidatorID(100) - s.me.SetCreator(invalidCreator) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - }, - }, - { - "ErrWrongEventSig", - heavycheck.ErrWrongEventSig, - func() { - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetCreator(3) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[1], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - }, - }, - { - "ErrMalformedTxSig", - heavycheck.ErrMalformedTxSig, - func() { - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetCreator(3) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - h := hash.BytesToEvent(bytes.Repeat([]byte{math.MaxUint8}, 32)) - tx1 := types.NewTx(&types.LegacyTx{ - Nonce: math.MaxUint64, - GasPrice: h.Big(), - Gas: math.MaxUint64, - To: nil, - Value: h.Big(), - Data: []byte{}, - }) - txs := types.Transactions{} - txs = append(txs, tx1) - s.me.SetTxs(txs) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - }, - }, - { - "ErrWrongPayloadHash", - heavycheck.ErrWrongPayloadHash, - func() { - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - s.me.SetCreator(3) - - invalidPayloadHash := hash.Hash{} - s.me.SetPayloadHash(invalidPayloadHash) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - }, - }, - { - "EpochVote().Epoch == 0", - nil, - func() { - ev := inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: 0, - Vote: hash.HexToHash("0x01"), - }, - } - - s.me.SetEpochVote(ev.Val) - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "EpochVote().Epoch != 0, matchPubkey returns heavycheck.ErrUnknownEpochEV", - heavycheck.ErrUnknownEpochEV, - func() { - ev := inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch, - Vote: hash.HexToHash("0x01"), - }, - } - - s.me.SetEpochVote(ev.Val) - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "EpochVote().Epoch != 0, matchPubkey returns epochcheck.ErrAuth", - epochcheck.ErrAuth, - func() { - ev := inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - } - - s.me.SetEpochVote(ev.Val) - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - invalidCreator := idx.ValidatorID(100) - s.me.SetCreator(invalidCreator) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "EpochVote().Epoch != 0, matchPubkey returns nil", - nil, - func() { - ev := inter.LlrSignedEpochVote{ - Val: inter.LlrEpochVote{ - Epoch: s.startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - } - - s.me.SetEpochVote(ev.Val) - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - - ev = inter.AsSignedEpochVote(s.me) - }, - }, - { - "BlockVote().Epoch == 0", - nil, - func() { - bv := inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: 0, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetBlockVotes(bv.Val) - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - }, - }, - { - "BlockVote().Epoch != 0, validateBVsEpoch returns nil", - nil, - func() { - bv := inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetBlockVotes(bv.Val) - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - }, - }, - { - "blockvote epoch is 0, block vote epoch does not match event epoch,matchPubkey returns nil", - nil, - func() { - bv := inter.LlrSignedBlockVotes{ - Val: inter.LlrBlockVotes{ - Start: 1, - Epoch: s.startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - } - - s.me.SetBlockVotes(bv.Val) - s.me.SetVersion(1) - s.me.SetEpoch(idx.Epoch(s.startEpoch)) - s.me.SetSeq(idx.Event(1)) - s.me.SetFrame(idx.Frame(1)) - s.me.SetLamport(idx.Lamport(1)) - s.me.SetCreator(3) - s.me.SetPayloadHash(inter.CalcPayloadHash(s.me)) - - sig, err := s.env.signer.Sign(s.env.pubkeys[2], s.me.HashToSign().Bytes()) - s.Require().NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - s.me.SetSig(sSig) - bv = inter.AsSignedBlockVotes(s.me) - }, - }, - } - - for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { - s.SetupSuite() - tc.pretest() - - err := s.env.checkers.Heavycheck.ValidateEvent(s.me) - - if tc.errExp != nil { - s.Require().Error(err) - s.Require().EqualError(err, tc.errExp.Error()) - } else { - s.Require().NoError(err) - } - }) - } -} - -func TestLLRHeavyCheckTestSuite(t *testing.T) { - t.Skip() // skip until fixed - suite.Run(t, new(LLRHeavyCheckTestSuite)) -} diff --git a/evm/go-x1/gossip/mps_test.go b/evm/go-x1/gossip/mps_test.go deleted file mode 100644 index 8b86a94..0000000 --- a/evm/go-x1/gossip/mps_test.go +++ /dev/null @@ -1,842 +0,0 @@ -package gossip - -import ( - "testing" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/eventcheck/basiccheck" - "github.com/Fantom-foundation/go-opera/eventcheck/heavycheck" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/logger" -) - -func copyBvs(bvs inter.LlrSignedBlockVotes) inter.LlrSignedBlockVotes { - cp := make([]hash.Hash, 0, len(bvs.Val.Votes)) - for _, v := range bvs.Val.Votes { - cp = append(cp, v) - } - bvs.Val.Votes = cp - return bvs -} - -func copyMP(mp inter.MisbehaviourProof) inter.MisbehaviourProof { - if mp.EventsDoublesign != nil { - cp := *mp.EventsDoublesign - mp.EventsDoublesign = &cp - } - if mp.BlockVoteDoublesign != nil { - cp := *mp.BlockVoteDoublesign - mp.BlockVoteDoublesign = &cp - for i := range mp.BlockVoteDoublesign.Pair { - mp.BlockVoteDoublesign.Pair[i] = copyBvs(mp.BlockVoteDoublesign.Pair[i]) - } - } - if mp.WrongBlockVote != nil { - cp := *mp.WrongBlockVote - mp.WrongBlockVote = &cp - for i := range mp.WrongBlockVote.Pals { - mp.WrongBlockVote.Pals[i] = copyBvs(mp.WrongBlockVote.Pals[i]) - } - } - if mp.EpochVoteDoublesign != nil { - cp := *mp.EpochVoteDoublesign - mp.EpochVoteDoublesign = &cp - } - if mp.WrongEpochVote != nil { - cp := *mp.WrongEpochVote - mp.WrongEpochVote = &cp - } - return mp -} - -func TestMisbehaviourProofsEventsDoublesign(t *testing.T) { - logger.SetTestMode(t) - require := require.New(t) - - const validatorsNum = 3 - - startEpoch := idx.Epoch(basiccheck.MaxLiableEpochs) - env := newTestEnv(startEpoch, validatorsNum) - defer env.Close() - - // move epoch further - _, err := env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - _, err = env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - require.Greater(env.store.GetEpoch(), startEpoch) - - correctMp := inter.MisbehaviourProof{ - EventsDoublesign: &inter.EventsDoublesign{ - Pair: [2]inter.SignedEventLocator{ - { - Locator: inter.EventLocator{ - Epoch: startEpoch, - Seq: 1, - Lamport: 1, - Creator: 1, - }, - }, - { - Locator: inter.EventLocator{ - Epoch: startEpoch, - Seq: 1, - Lamport: 2, - Creator: 1, - }, - }, - }, - }, - } - - // sign - for i, p := range correctMp.EventsDoublesign.Pair { - sig, err := env.signer.Sign(env.pubkeys[0], p.Locator.HashToSign().Bytes()) - require.NoError(err) - copy(correctMp.EventsDoublesign.Pair[i].Sig[:], sig) - } - - tooLateMp := copyMP(correctMp) - tooLateMp.EventsDoublesign.Pair[0].Locator.Epoch = 1 - tooLateMp.EventsDoublesign.Pair[1].Locator.Epoch = 1 - err = env.ApplyMPs(nextEpoch, tooLateMp) - require.ErrorIs(err, basiccheck.ErrMPTooLate) - - wrongEpochMp := copyMP(correctMp) - wrongEpochMp.EventsDoublesign.Pair[0].Locator.Epoch-- - err = env.ApplyMPs(nextEpoch, wrongEpochMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - wrongSeqMp := copyMP(correctMp) - wrongSeqMp.EventsDoublesign.Pair[0].Locator.Seq-- - err = env.ApplyMPs(nextEpoch, wrongSeqMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - wrongCreatorMp := copyMP(correctMp) - wrongCreatorMp.EventsDoublesign.Pair[0].Locator.Creator++ - err = env.ApplyMPs(nextEpoch, wrongCreatorMp) - require.ErrorIs(err, basiccheck.ErrWrongCreatorMP) - - sameEventsMp := copyMP(correctMp) - sameEventsMp.EventsDoublesign.Pair[0] = sameEventsMp.EventsDoublesign.Pair[1] - err = env.ApplyMPs(nextEpoch, sameEventsMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - for i := range correctMp.EventsDoublesign.Pair { - wrongSigMp := copyMP(correctMp) - wrongSigMp.EventsDoublesign.Pair[i].Sig[0]++ - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - for i := range correctMp.EventsDoublesign.Pair { - wrongSigMp := copyMP(correctMp) - wrongSigMp.EventsDoublesign.Pair[i].Locator.BaseHash = hash.HexToHash("0x10") - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - wrongAuthEpochMp := copyMP(correctMp) - wrongAuthEpochMp.EventsDoublesign.Pair[0].Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.EventsDoublesign.Pair[1].Locator.Epoch = startEpoch - 1 - err = env.ApplyMPs(nextEpoch, wrongAuthEpochMp) - require.ErrorIs(err, heavycheck.ErrUnknownEpochEventLocator) - - err = env.ApplyMPs(nextEpoch, correctMp) - require.NoError(err) - require.Equal(idx.Validator(2), env.store.GetValidators().Len()) - require.False(env.store.GetValidators().Exists(1)) -} - -func TestMisbehaviourProofsBlockVoteDoublesign(t *testing.T) { - logger.SetTestMode(t) - require := require.New(t) - - const validatorsNum = 3 - - startEpoch := idx.Epoch(basiccheck.MaxLiableEpochs) - env := newTestEnv(basiccheck.MaxLiableEpochs, validatorsNum) - defer env.Close() - - // move epoch further - _, err := env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - _, err = env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - require.Greater(env.store.GetEpoch(), startEpoch) - - correctMp := inter.MisbehaviourProof{ - BlockVoteDoublesign: &inter.BlockVoteDoublesign{ - Block: env.store.GetLatestBlockIndex(), - Pair: [2]inter.LlrSignedBlockVotes{ - { - Val: inter.LlrBlockVotes{ - Start: env.store.GetLatestBlockIndex() - 1, - Epoch: startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - }, - { - Val: inter.LlrBlockVotes{ - Start: env.store.GetLatestBlockIndex(), - Epoch: startEpoch, - Votes: []hash.Hash{ - hash.HexToHash("0x02"), - }, - }, - }, - }, - }, - } - - // sign - for i, p := range correctMp.BlockVoteDoublesign.Pair { - e := &inter.MutableEventPayload{} - e.SetVersion(1) - e.SetBlockVotes(p.Val) - e.SetEpoch(env.store.GetEpoch() - idx.Epoch(i)) - e.SetCreator(2) - e.SetPayloadHash(inter.CalcPayloadHash(e)) - - sig, err := env.signer.Sign(env.pubkeys[1], e.HashToSign().Bytes()) - require.NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - e.SetSig(sSig) - - correctMp.BlockVoteDoublesign.Pair[i] = inter.AsSignedBlockVotes(e) - } - - sameVotesMp := copyMP(correctMp) - sameVotesMp.BlockVoteDoublesign.Pair[0].Val.Votes[1] = sameVotesMp.BlockVoteDoublesign.Pair[1].Val.Votes[0] - err = env.ApplyMPs(nextEpoch, sameVotesMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - differentEpochsMp := sameVotesMp - differentEpochsMp.BlockVoteDoublesign.Pair[0].Val.Epoch++ - err = env.ApplyMPs(nextEpoch, sameVotesMp) - require.ErrorIs(err, heavycheck.ErrWrongPayloadHash) - - for i := range correctMp.BlockVoteDoublesign.Pair { - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.BlockVoteDoublesign.Pair[i].Val.Votes = []hash.Hash{} - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.MalformedBVs) - } - for i := range correctMp.BlockVoteDoublesign.Pair { - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.BlockVoteDoublesign.Pair[i].Val.Start -= 2 - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.ErrWrongMP) - } - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.BlockVoteDoublesign.Pair[1].Val.Start-- - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.ErrWrongMP) - - for i := range correctMp.BlockVoteDoublesign.Pair { - tooLateMp := copyMP(correctMp) - tooLateMp.BlockVoteDoublesign.Pair[i].Val.Epoch = 1 - err = env.ApplyMPs(nextEpoch, tooLateMp) - require.ErrorIs(err, basiccheck.ErrMPTooLate) - } - - for i := range correctMp.BlockVoteDoublesign.Pair { - futureEpochMp := copyMP(correctMp) - futureEpochMp.BlockVoteDoublesign.Pair[i].Signed.Locator.Epoch = futureEpochMp.BlockVoteDoublesign.Pair[i].Val.Epoch - 1 - err = env.ApplyMPs(nextEpoch, futureEpochMp) - require.ErrorIs(err, basiccheck.FutureBVsEpoch) - } - - wrongCreatorMp := copyMP(correctMp) - wrongCreatorMp.BlockVoteDoublesign.Pair[0].Signed.Locator.Creator++ - err = env.ApplyMPs(nextEpoch, wrongCreatorMp) - require.ErrorIs(err, basiccheck.ErrWrongCreatorMP) - - sameEventsMp := copyMP(correctMp) - sameEventsMp.BlockVoteDoublesign.Pair[0] = sameEventsMp.BlockVoteDoublesign.Pair[1] - err = env.ApplyMPs(nextEpoch, sameEventsMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - for i := range correctMp.BlockVoteDoublesign.Pair { - wrongSigMp := copyMP(correctMp) - wrongSigMp.BlockVoteDoublesign.Pair[i].Signed.Sig[0]++ - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - for i := range correctMp.BlockVoteDoublesign.Pair { - wrongSigMp := copyMP(correctMp) - wrongSigMp.BlockVoteDoublesign.Pair[i].Signed.Locator.BaseHash = hash.HexToHash("0x10") - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - wrongAuthEpochMp := copyMP(correctMp) - wrongAuthEpochMp.BlockVoteDoublesign.Pair[0].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.BlockVoteDoublesign.Pair[0].Val.Epoch = startEpoch - 1 - wrongAuthEpochMp.BlockVoteDoublesign.Pair[1].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.BlockVoteDoublesign.Pair[1].Val.Epoch = startEpoch - 1 - err = env.ApplyMPs(nextEpoch, wrongAuthEpochMp) - require.ErrorIs(err, heavycheck.ErrUnknownEpochBVs) - - err = env.ApplyMPs(nextEpoch, correctMp) - require.NoError(err) - require.Equal(idx.Validator(2), env.store.GetValidators().Len()) - require.False(env.store.GetValidators().Exists(2)) -} - -func TestMisbehaviourProofsWrongBlockVote(t *testing.T) { - logger.SetTestMode(t) - require := require.New(t) - - const validatorsNum = 3 - - startEpoch := idx.Epoch(basiccheck.MaxLiableEpochs) - env := newTestEnv(startEpoch, validatorsNum) - defer env.Close() - - // move epoch further - _, err := env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - _, err = env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - require.Greater(env.store.GetEpoch(), startEpoch) - - correctMp := inter.MisbehaviourProof{ - WrongBlockVote: &inter.WrongBlockVote{ - Block: env.store.GetLatestBlockIndex(), - Pals: [2]inter.LlrSignedBlockVotes{ - { - Val: inter.LlrBlockVotes{ - Start: env.store.GetLatestBlockIndex() - 1, - Epoch: startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - }, - { - Val: inter.LlrBlockVotes{ - Start: env.store.GetLatestBlockIndex(), - Epoch: startEpoch + 1, - Votes: []hash.Hash{ - hash.HexToHash("0x01"), - }, - }, - }, - }, - WrongEpoch: false, - }, - } - - sign := func(mp *inter.MisbehaviourProof) { - // sign - for i, p := range mp.WrongBlockVote.Pals { - e := &inter.MutableEventPayload{} - e.SetVersion(1) - e.SetBlockVotes(p.Val) - e.SetEpoch(env.store.GetEpoch() - idx.Epoch(i)) - e.SetCreator(idx.ValidatorID(i + 1)) - e.SetPayloadHash(inter.CalcPayloadHash(e)) - - sig, err := env.signer.Sign(env.pubkeys[i], e.HashToSign().Bytes()) - require.NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - e.SetSig(sSig) - - mp.WrongBlockVote.Pals[i] = inter.AsSignedBlockVotes(e) - } - } - sign(&correctMp) - - differentVotesMp := copyMP(correctMp) - differentVotesMp.WrongBlockVote.Pals[0].Val.Votes[1] = hash.HexToHash("0x02") - err = env.ApplyMPs(nextEpoch, differentVotesMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - for i := range correctMp.WrongBlockVote.Pals { - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.WrongBlockVote.Pals[i].Val.Votes = []hash.Hash{} - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.MalformedBVs) - } - for i := range correctMp.WrongBlockVote.Pals { - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.WrongBlockVote.Pals[i].Val.Start -= 2 - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.ErrWrongMP) - } - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.WrongBlockVote.Pals[1].Val.Start-- - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.ErrWrongMP) - - for i := range correctMp.WrongBlockVote.Pals { - tooLateMp := copyMP(correctMp) - tooLateMp.WrongBlockVote.Pals[i].Val.Epoch = 1 - err = env.ApplyMPs(nextEpoch, tooLateMp) - require.ErrorIs(err, basiccheck.ErrMPTooLate) - } - - for i := range correctMp.WrongBlockVote.Pals { - futureEpochMp := copyMP(correctMp) - futureEpochMp.WrongBlockVote.Pals[i].Signed.Locator.Epoch = futureEpochMp.WrongBlockVote.Pals[i].Val.Epoch - 1 - err = env.ApplyMPs(nextEpoch, futureEpochMp) - require.ErrorIs(err, basiccheck.FutureBVsEpoch) - } - - sameCreatorMp := copyMP(correctMp) - sameCreatorMp.WrongBlockVote.Pals[0].Signed.Locator.Creator = sameCreatorMp.WrongBlockVote.Pals[1].Signed.Locator.Creator - err = env.ApplyMPs(nextEpoch, sameCreatorMp) - require.ErrorIs(err, basiccheck.ErrWrongCreatorMP) - - for i := range correctMp.WrongBlockVote.Pals { - wrongSigMp := copyMP(correctMp) - wrongSigMp.WrongBlockVote.Pals[i].Signed.Sig[0]++ - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - for i := range correctMp.WrongBlockVote.Pals { - wrongSigMp := copyMP(correctMp) - wrongSigMp.WrongBlockVote.Pals[i].Signed.Locator.BaseHash = hash.HexToHash("0x10") - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - wrongAuthEpochMp := copyMP(correctMp) - wrongAuthEpochMp.WrongBlockVote.Pals[0].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.WrongBlockVote.Pals[0].Val.Epoch = startEpoch - 1 - wrongAuthEpochMp.WrongBlockVote.Pals[1].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.WrongBlockVote.Pals[1].Val.Epoch = startEpoch - 1 - err = env.ApplyMPs(nextEpoch, wrongAuthEpochMp) - require.ErrorIs(err, heavycheck.ErrUnknownEpochBVs) - - goodVotesMp := copyMP(correctMp) - goodVotesMp.WrongBlockVote.Pals[0].Val.Votes[1] = env.store.GetFullBlockRecord(goodVotesMp.WrongBlockVote.Block).Hash() - goodVotesMp.WrongBlockVote.Pals[1].Val.Votes[0] = env.store.GetFullBlockRecord(goodVotesMp.WrongBlockVote.Block).Hash() - err = env.ApplyMPs(nextEpoch, goodVotesMp) - require.ErrorIs(err, heavycheck.ErrWrongPayloadHash) - sign(&goodVotesMp) - err = env.ApplyMPs(nextEpoch, goodVotesMp) - require.NoError(err) - require.Equal(idx.Validator(3), env.store.GetValidators().Len()) - - err = env.ApplyMPs(nextEpoch, correctMp) - require.NoError(err) - require.Equal(idx.Validator(1), env.store.GetValidators().Len()) - require.False(env.store.GetValidators().Exists(1)) - require.False(env.store.GetValidators().Exists(2)) -} - -func TestMisbehaviourProofsWrongBlockEpoch(t *testing.T) { - logger.SetTestMode(t) - require := require.New(t) - - const validatorsNum = 3 - - startEpoch := idx.Epoch(basiccheck.MaxLiableEpochs) - env := newTestEnv(startEpoch, validatorsNum) - defer env.Close() - - // move epoch further - _, err := env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - _, err = env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - require.Greater(env.store.GetEpoch(), startEpoch) - - correctMp := inter.MisbehaviourProof{ - WrongBlockVote: &inter.WrongBlockVote{ - Block: env.store.GetLatestBlockIndex(), - Pals: [2]inter.LlrSignedBlockVotes{ - { - Val: inter.LlrBlockVotes{ - Start: env.store.GetLatestBlockIndex() - 1, - Epoch: startEpoch, - Votes: []hash.Hash{ - hash.Zero, - hash.HexToHash("0x01"), - }, - }, - }, - { - Val: inter.LlrBlockVotes{ - Start: env.store.GetLatestBlockIndex(), - Epoch: startEpoch, - Votes: []hash.Hash{ - hash.HexToHash("0x02"), - }, - }, - }, - }, - WrongEpoch: true, - }, - } - require.Greater(env.store.GetEpoch(), correctMp.WrongBlockVote.Pals[0].Val.Epoch) - - // sign - sign := func(mp *inter.MisbehaviourProof) { - for i, p := range mp.WrongBlockVote.Pals { - e := &inter.MutableEventPayload{} - e.SetVersion(1) - e.SetBlockVotes(p.Val) - e.SetEpoch(env.store.GetEpoch() - idx.Epoch(i)) - e.SetCreator(idx.ValidatorID(i + 1)) - e.SetPayloadHash(inter.CalcPayloadHash(e)) - - sig, err := env.signer.Sign(env.pubkeys[i], e.HashToSign().Bytes()) - require.NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - e.SetSig(sSig) - - mp.WrongBlockVote.Pals[i] = inter.AsSignedBlockVotes(e) - } - } - sign(&correctMp) - - // it allows same votes, as it failed verification only on last step - sameVotesMp := copyMP(correctMp) - sameVotesMp.WrongBlockVote.Pals[0].Val.Votes[1] = sameVotesMp.WrongBlockVote.Pals[1].Val.Votes[0] - err = env.ApplyMPs(nextEpoch, sameVotesMp) - require.ErrorIs(err, heavycheck.ErrWrongPayloadHash) - - differentEpochsMp := copyMP(correctMp) - differentEpochsMp.WrongBlockVote.Pals[0].Val.Epoch++ - err = env.ApplyMPs(nextEpoch, differentEpochsMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - for i := range correctMp.WrongBlockVote.Pals { - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.WrongBlockVote.Pals[i].Val.Votes = []hash.Hash{} - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.MalformedBVs) - } - for i := range correctMp.WrongBlockVote.Pals { - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.WrongBlockVote.Pals[i].Val.Start -= 2 - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.ErrWrongMP) - } - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.WrongBlockVote.Pals[1].Val.Start-- - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.ErrWrongMP) - - for i := range correctMp.WrongBlockVote.Pals { - tooLateMp := copyMP(correctMp) - tooLateMp.WrongBlockVote.Pals[i].Val.Epoch = 1 - err = env.ApplyMPs(nextEpoch, tooLateMp) - require.ErrorIs(err, basiccheck.ErrMPTooLate) - } - - for i := range correctMp.WrongBlockVote.Pals { - futureEpochMp := copyMP(correctMp) - futureEpochMp.WrongBlockVote.Pals[i].Signed.Locator.Epoch = futureEpochMp.WrongBlockVote.Pals[i].Val.Epoch - 1 - err = env.ApplyMPs(nextEpoch, futureEpochMp) - require.ErrorIs(err, basiccheck.FutureBVsEpoch) - } - - sameCreatorMp := copyMP(correctMp) - sameCreatorMp.WrongBlockVote.Pals[0].Signed.Locator.Creator = sameCreatorMp.WrongBlockVote.Pals[1].Signed.Locator.Creator - err = env.ApplyMPs(nextEpoch, sameCreatorMp) - require.ErrorIs(err, basiccheck.ErrWrongCreatorMP) - - for i := range correctMp.WrongBlockVote.Pals { - wrongSigMp := copyMP(correctMp) - wrongSigMp.WrongBlockVote.Pals[i].Signed.Sig[0]++ - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - for i := range correctMp.WrongBlockVote.Pals { - wrongSigMp := copyMP(correctMp) - wrongSigMp.WrongBlockVote.Pals[i].Signed.Locator.BaseHash = hash.HexToHash("0x10") - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - wrongAuthEpochMp := copyMP(correctMp) - wrongAuthEpochMp.WrongBlockVote.Pals[0].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.WrongBlockVote.Pals[0].Val.Epoch = startEpoch - 1 - wrongAuthEpochMp.WrongBlockVote.Pals[1].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.WrongBlockVote.Pals[1].Val.Epoch = startEpoch - 1 - err = env.ApplyMPs(nextEpoch, wrongAuthEpochMp) - require.ErrorIs(err, heavycheck.ErrUnknownEpochBVs) - - goodEpochMp := copyMP(correctMp) - goodEpochMp.WrongBlockVote.Pals[0].Val.Epoch = env.store.FindBlockEpoch(goodEpochMp.WrongBlockVote.Block) - goodEpochMp.WrongBlockVote.Pals[1].Val.Epoch = env.store.FindBlockEpoch(goodEpochMp.WrongBlockVote.Block) - err = env.ApplyMPs(nextEpoch, goodEpochMp) - require.ErrorIs(err, heavycheck.ErrWrongPayloadHash) - sign(&goodEpochMp) - err = env.ApplyMPs(nextEpoch, goodEpochMp) - require.NoError(err) - require.Equal(idx.Validator(3), env.store.GetValidators().Len()) - - err = env.ApplyMPs(nextEpoch, correctMp) - require.NoError(err) - require.Equal(idx.Validator(1), env.store.GetValidators().Len()) - require.False(env.store.GetValidators().Exists(1)) - require.False(env.store.GetValidators().Exists(2)) -} - -func TestMisbehaviourProofsEpochVoteDoublesign(t *testing.T) { - logger.SetTestMode(t) - require := require.New(t) - - const validatorsNum = 3 - - startEpoch := idx.Epoch(basiccheck.MaxLiableEpochs) - env := newTestEnv(startEpoch, validatorsNum) - defer env.Close() - - // move epoch further - _, err := env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - _, err = env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - require.Greater(env.store.GetEpoch(), startEpoch) - - correctMp := inter.MisbehaviourProof{ - EpochVoteDoublesign: &inter.EpochVoteDoublesign{ - Pair: [2]inter.LlrSignedEpochVote{ - { - Val: inter.LlrEpochVote{ - Epoch: startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - }, - { - Val: inter.LlrEpochVote{ - Epoch: startEpoch + 1, - Vote: hash.HexToHash("0x02"), - }, - }, - }, - }, - } - - // sign - for i, p := range correctMp.EpochVoteDoublesign.Pair { - e := &inter.MutableEventPayload{} - e.SetVersion(1) - e.SetEpochVote(p.Val) - e.SetEpoch(env.store.GetEpoch() - idx.Epoch(i)) - e.SetCreator(3) - e.SetPayloadHash(inter.CalcPayloadHash(e)) - - sig, err := env.signer.Sign(env.pubkeys[2], e.HashToSign().Bytes()) - require.NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - e.SetSig(sSig) - - correctMp.EpochVoteDoublesign.Pair[i] = inter.AsSignedEpochVote(e) - } - - sameVotesMp := copyMP(correctMp) - sameVotesMp.EpochVoteDoublesign.Pair[0].Val.Vote = sameVotesMp.EpochVoteDoublesign.Pair[1].Val.Vote - err = env.ApplyMPs(nextEpoch, sameVotesMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - differentEpochsMp := copyMP(correctMp) - differentEpochsMp.EpochVoteDoublesign.Pair[0].Val.Epoch++ - err = env.ApplyMPs(nextEpoch, differentEpochsMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.EpochVoteDoublesign.Pair[1].Val.Epoch = 0 - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.MalformedEV) - - tooLateMp := copyMP(correctMp) - tooLateMp.EpochVoteDoublesign.Pair[0].Val.Epoch = 1 - tooLateMp.EpochVoteDoublesign.Pair[1].Val.Epoch = 1 - err = env.ApplyMPs(nextEpoch, tooLateMp) - require.ErrorIs(err, basiccheck.ErrMPTooLate) - - for i := range correctMp.EpochVoteDoublesign.Pair { - futureEpochMp := copyMP(correctMp) - futureEpochMp.EpochVoteDoublesign.Pair[i].Signed.Locator.Epoch = futureEpochMp.EpochVoteDoublesign.Pair[i].Val.Epoch - 1 - err = env.ApplyMPs(nextEpoch, futureEpochMp) - require.ErrorIs(err, basiccheck.FutureEVEpoch) - } - - wrongCreatorMp := copyMP(correctMp) - wrongCreatorMp.EpochVoteDoublesign.Pair[0].Signed.Locator.Creator++ - err = env.ApplyMPs(nextEpoch, wrongCreatorMp) - require.ErrorIs(err, basiccheck.ErrWrongCreatorMP) - - sameEventsMp := copyMP(correctMp) - sameEventsMp.EpochVoteDoublesign.Pair[0] = sameEventsMp.EpochVoteDoublesign.Pair[1] - err = env.ApplyMPs(nextEpoch, sameEventsMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - for i := range correctMp.EpochVoteDoublesign.Pair { - wrongSigMp := copyMP(correctMp) - wrongSigMp.EpochVoteDoublesign.Pair[i].Signed.Sig[0]++ - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - for i := range correctMp.EpochVoteDoublesign.Pair { - wrongSigMp := copyMP(correctMp) - wrongSigMp.EpochVoteDoublesign.Pair[i].Signed.Locator.BaseHash = hash.HexToHash("0x10") - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - wrongAuthEpochMp := copyMP(correctMp) - wrongAuthEpochMp.EpochVoteDoublesign.Pair[0].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.EpochVoteDoublesign.Pair[0].Val.Epoch = startEpoch - 1 - wrongAuthEpochMp.EpochVoteDoublesign.Pair[1].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.EpochVoteDoublesign.Pair[1].Val.Epoch = startEpoch - 1 - err = env.ApplyMPs(nextEpoch, wrongAuthEpochMp) - require.ErrorIs(err, heavycheck.ErrUnknownEpochEV) - - err = env.ApplyMPs(nextEpoch, correctMp) - require.NoError(err) - require.Equal(idx.Validator(2), env.store.GetValidators().Len()) - require.False(env.store.GetValidators().Exists(3)) -} - -func TestMisbehaviourProofsWrongVote(t *testing.T) { - logger.SetTestMode(t) - require := require.New(t) - - const validatorsNum = 3 - - startEpoch := idx.Epoch(basiccheck.MaxLiableEpochs) - env := newTestEnv(startEpoch, validatorsNum) - defer env.Close() - - // move epoch further - _, err := env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - _, err = env.ApplyTxs(nextEpoch, env.Transfer(1, 1, common.Big0)) - require.NoError(err) - require.Greater(env.store.GetEpoch(), startEpoch) - - correctMp := inter.MisbehaviourProof{ - WrongEpochVote: &inter.WrongEpochVote{ - Pals: [2]inter.LlrSignedEpochVote{ - { - Val: inter.LlrEpochVote{ - Epoch: startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - }, - { - Val: inter.LlrEpochVote{ - Epoch: startEpoch + 1, - Vote: hash.HexToHash("0x01"), - }, - }, - }, - }, - } - - // sign - sign := func(mp *inter.MisbehaviourProof) { - for i, p := range mp.WrongEpochVote.Pals { - e := &inter.MutableEventPayload{} - e.SetVersion(1) - e.SetEpochVote(p.Val) - e.SetEpoch(env.store.GetEpoch() - idx.Epoch(i)) - e.SetCreator(idx.ValidatorID(i + 1)) - e.SetPayloadHash(inter.CalcPayloadHash(e)) - - sig, err := env.signer.Sign(env.pubkeys[i], e.HashToSign().Bytes()) - require.NoError(err) - sSig := inter.Signature{} - copy(sSig[:], sig) - e.SetSig(sSig) - - mp.WrongEpochVote.Pals[i] = inter.AsSignedEpochVote(e) - } - } - sign(&correctMp) - - differentVotesMp := copyMP(correctMp) - differentVotesMp.WrongEpochVote.Pals[0].Val.Vote = hash.HexToHash("0x02") - err = env.ApplyMPs(nextEpoch, differentVotesMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - differentEpochsMp := copyMP(correctMp) - differentEpochsMp.WrongEpochVote.Pals[0].Val.Epoch++ - err = env.ApplyMPs(nextEpoch, differentEpochsMp) - require.ErrorIs(err, basiccheck.ErrNoCrimeInMP) - - malformedVotesMp := copyMP(correctMp) - malformedVotesMp.WrongEpochVote.Pals[1].Val.Epoch = 0 - err = env.ApplyMPs(nextEpoch, malformedVotesMp) - require.ErrorIs(err, basiccheck.MalformedEV) - - tooLateMp := copyMP(correctMp) - tooLateMp.WrongEpochVote.Pals[0].Val.Epoch = 1 - tooLateMp.WrongEpochVote.Pals[1].Val.Epoch = 1 - err = env.ApplyMPs(nextEpoch, tooLateMp) - require.ErrorIs(err, basiccheck.ErrMPTooLate) - - for i := range correctMp.WrongEpochVote.Pals { - futureEpochMp := copyMP(correctMp) - futureEpochMp.WrongEpochVote.Pals[i].Signed.Locator.Epoch = futureEpochMp.WrongEpochVote.Pals[i].Val.Epoch - 1 - err = env.ApplyMPs(nextEpoch, futureEpochMp) - require.ErrorIs(err, basiccheck.FutureEVEpoch) - } - - sameCreatorMp := copyMP(correctMp) - sameCreatorMp.WrongEpochVote.Pals[0].Signed.Locator.Creator = sameCreatorMp.WrongEpochVote.Pals[1].Signed.Locator.Creator - err = env.ApplyMPs(nextEpoch, sameCreatorMp) - require.ErrorIs(err, basiccheck.ErrWrongCreatorMP) - - for i := range correctMp.WrongEpochVote.Pals { - wrongSigMp := copyMP(correctMp) - wrongSigMp.WrongEpochVote.Pals[i].Signed.Sig[0]++ - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - for i := range correctMp.WrongEpochVote.Pals { - wrongSigMp := copyMP(correctMp) - wrongSigMp.WrongEpochVote.Pals[i].Signed.Locator.BaseHash = hash.HexToHash("0x10") - err = env.ApplyMPs(nextEpoch, wrongSigMp) - require.ErrorIs(err, heavycheck.ErrWrongEventSig) - } - - wrongAuthEpochMp := copyMP(correctMp) - wrongAuthEpochMp.WrongEpochVote.Pals[0].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.WrongEpochVote.Pals[0].Val.Epoch = startEpoch - 1 - wrongAuthEpochMp.WrongEpochVote.Pals[1].Signed.Locator.Epoch = startEpoch - 1 - wrongAuthEpochMp.WrongEpochVote.Pals[1].Val.Epoch = startEpoch - 1 - err = env.ApplyMPs(nextEpoch, wrongAuthEpochMp) - require.ErrorIs(err, heavycheck.ErrUnknownEpochEV) - - goodVotesMp := copyMP(correctMp) - goodVotesMp.WrongEpochVote.Pals[0].Val.Vote = env.store.GetFullEpochRecord(goodVotesMp.WrongEpochVote.Pals[0].Val.Epoch).Hash() - goodVotesMp.WrongEpochVote.Pals[1].Val.Vote = env.store.GetFullEpochRecord(goodVotesMp.WrongEpochVote.Pals[1].Val.Epoch).Hash() - err = env.ApplyMPs(nextEpoch, goodVotesMp) - require.ErrorIs(err, heavycheck.ErrWrongPayloadHash) - sign(&goodVotesMp) - err = env.ApplyMPs(nextEpoch, goodVotesMp) - require.NoError(err) - require.Equal(idx.Validator(3), env.store.GetValidators().Len()) - - err = env.ApplyMPs(nextEpoch, correctMp) - require.NoError(err) - require.Equal(idx.Validator(1), env.store.GetValidators().Len()) - require.False(env.store.GetValidators().Exists(1)) - require.False(env.store.GetValidators().Exists(2)) -} diff --git a/evm/go-x1/gossip/peer.go b/evm/go-x1/gossip/peer.go deleted file mode 100644 index 95139b6..0000000 --- a/evm/go-x1/gossip/peer.go +++ /dev/null @@ -1,589 +0,0 @@ -package gossip - -import ( - "errors" - "fmt" - "sync" - "sync/atomic" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/datasemaphore" - mapset "github.com/deckarep/golang-set" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/protocols/snap" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brstream" - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvstream" - "github.com/Fantom-foundation/go-opera/gossip/protocols/dag/dagstream" - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epstream" - "github.com/Fantom-foundation/go-opera/inter" -) - -var ( - errNotRegistered = errors.New("peer is not registered") -) - -const ( - handshakeTimeout = 5 * time.Second -) - -// PeerInfo represents a short summary of the sub-protocol metadata known -// about a connected peer. -type PeerInfo struct { - Version uint `json:"version"` // protocol version negotiated - Epoch idx.Epoch `json:"epoch"` - NumOfBlocks idx.Block `json:"blocks"` -} - -type broadcastItem struct { - Code uint64 - Raw rlp.RawValue -} - -type peer struct { - id string - - cfg PeerCacheConfig - - *p2p.Peer - rw p2p.MsgReadWriter - - version uint // Protocol version negotiated - - knownTxs mapset.Set // Set of transaction hashes known to be known by this peer - knownEvents mapset.Set // Set of event hashes known to be known by this peer - queue chan broadcastItem // queue of items to send - queuedDataSemaphore *datasemaphore.DataSemaphore - term chan struct{} // Termination channel to stop the broadcaster - - progress PeerProgress - - snapExt *snapPeer // Satellite `snap` connection - syncDrop *time.Timer // Connection dropper if `eth` sync progress isn't validated in time - snapWait chan struct{} // Notification channel for snap connections - - useless uint32 - - sync.RWMutex -} - -func (p *peer) Useless() bool { - return atomic.LoadUint32(&p.useless) != 0 -} - -func (p *peer) SetUseless() { - atomic.StoreUint32(&p.useless, 1) -} - -func (p *peer) SetProgress(x PeerProgress) { - p.Lock() - defer p.Unlock() - - p.progress = x -} - -func (p *peer) InterestedIn(h hash.Event) bool { - e := h.Epoch() - - p.RLock() - defer p.RUnlock() - - return e != 0 && - p.progress.Epoch != 0 && - (e == p.progress.Epoch || e == p.progress.Epoch+1) && - !p.knownEvents.Contains(h) -} - -func (a *PeerProgress) Less(b PeerProgress) bool { - if a.Epoch != b.Epoch { - return a.Epoch < b.Epoch - } - return a.LastBlockIdx < b.LastBlockIdx -} - -func newPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter, cfg PeerCacheConfig) *peer { - peer := &peer{ - cfg: cfg, - Peer: p, - rw: rw, - version: version, - id: p.ID().String(), - knownTxs: mapset.NewSet(), - knownEvents: mapset.NewSet(), - queue: make(chan broadcastItem, cfg.MaxQueuedItems), - queuedDataSemaphore: datasemaphore.New(dag.Metric{cfg.MaxQueuedItems, cfg.MaxQueuedSize}, getSemaphoreWarningFn("Peers queue")), - term: make(chan struct{}), - } - - go peer.broadcast(peer.queue) - - return peer -} - -// broadcast is a write loop that multiplexes event propagations, announcements -// and transaction broadcasts into the remote peer. The goal is to have an async -// writer that does not lock up node internals. -func (p *peer) broadcast(queue chan broadcastItem) { - for { - select { - case item := <-queue: - _ = p2p.Send(p.rw, item.Code, item.Raw) - p.queuedDataSemaphore.Release(memSize(item.Raw)) - - case <-p.term: - return - } - } -} - -// Close signals the broadcast goroutine to terminate. -func (p *peer) Close() { - p.queuedDataSemaphore.Terminate() - close(p.term) -} - -// Info gathers and returns a collection of metadata known about a peer. -func (p *peer) Info() *PeerInfo { - return &PeerInfo{ - Version: p.version, - Epoch: p.progress.Epoch, - NumOfBlocks: p.progress.LastBlockIdx, - } -} - -// MarkEvent marks a event as known for the peer, ensuring that the event will -// never be propagated to this particular peer. -func (p *peer) MarkEvent(hash hash.Event) { - // If we reached the memory allowance, drop a previously known event hash - for p.knownEvents.Cardinality() >= p.cfg.MaxKnownEvents { - p.knownEvents.Pop() - } - p.knownEvents.Add(hash) -} - -// MarkTransaction marks a transaction as known for the peer, ensuring that it -// will never be propagated to this particular peer. -func (p *peer) MarkTransaction(hash common.Hash) { - // If we reached the memory allowance, drop a previously known transaction hash - for p.knownTxs.Cardinality() >= p.cfg.MaxKnownTxs { - p.knownTxs.Pop() - } - p.knownTxs.Add(hash) -} - -// SendTransactions sends transactions to the peer and includes the hashes -// in its transaction hash set for future reference. -func (p *peer) SendTransactions(txs types.Transactions) error { - // Mark all the transactions as known, but ensure we don't overflow our limits - for _, tx := range txs { - p.knownTxs.Add(tx.Hash()) - } - for p.knownTxs.Cardinality() >= p.cfg.MaxKnownTxs { - p.knownTxs.Pop() - } - return p2p.Send(p.rw, EvmTxsMsg, txs) -} - -// SendTransactionHashes sends transaction hashess to the peer and includes the hashes -// in its transaction hash set for future reference. -func (p *peer) SendTransactionHashes(txids []common.Hash) error { - // Mark all the transactions as known, but ensure we don't overflow our limits - for _, txid := range txids { - p.knownTxs.Add(txid) - } - for p.knownTxs.Cardinality() >= p.cfg.MaxKnownTxs { - p.knownTxs.Pop() - } - return p2p.Send(p.rw, NewEvmTxHashesMsg, txids) -} - -func memSize(v rlp.RawValue) dag.Metric { - return dag.Metric{1, uint64(len(v) + 1024)} -} - -func (p *peer) asyncSendEncodedItem(raw rlp.RawValue, code uint64, queue chan broadcastItem) bool { - if !p.queuedDataSemaphore.TryAcquire(memSize(raw)) { - return false - } - item := broadcastItem{ - Code: code, - Raw: raw, - } - select { - case queue <- item: - return true - case <-p.term: - default: - } - p.queuedDataSemaphore.Release(memSize(raw)) - return false -} - -func (p *peer) asyncSendNonEncodedItem(value interface{}, code uint64, queue chan broadcastItem) bool { - raw, err := rlp.EncodeToBytes(value) - if err != nil { - return false - } - return p.asyncSendEncodedItem(raw, code, queue) -} - -func (p *peer) enqueueSendEncodedItem(raw rlp.RawValue, code uint64, queue chan broadcastItem) { - if !p.queuedDataSemaphore.Acquire(memSize(raw), 10*time.Second) { - return - } - item := broadcastItem{ - Code: code, - Raw: raw, - } - select { - case queue <- item: - return - case <-p.term: - } - p.queuedDataSemaphore.Release(memSize(raw)) -} - -func (p *peer) enqueueSendNonEncodedItem(value interface{}, code uint64, queue chan broadcastItem) { - raw, err := rlp.EncodeToBytes(value) - if err != nil { - return - } - p.enqueueSendEncodedItem(raw, code, queue) -} - -func SplitTransactions(txs types.Transactions, fn func(types.Transactions)) { - // divide big batch into smaller ones - for len(txs) > 0 { - batchSize := 0 - var batch types.Transactions - for i, tx := range txs { - batchSize += int(tx.Size()) + 1024 - batch = txs[:i+1] - if batchSize >= softResponseLimitSize || i+1 >= softLimitItems { - break - } - } - txs = txs[len(batch):] - fn(batch) - } -} - -// AsyncSendTransactions queues list of transactions propagation to a remote -// peer. If the peer's broadcast queue is full, the transactions are silently dropped. -func (p *peer) AsyncSendTransactions(txs types.Transactions, queue chan broadcastItem) { - if p.asyncSendNonEncodedItem(txs, EvmTxsMsg, queue) { - // Mark all the transactions as known, but ensure we don't overflow our limits - for _, tx := range txs { - p.knownTxs.Add(tx.Hash()) - } - for p.knownTxs.Cardinality() >= p.cfg.MaxKnownTxs { - p.knownTxs.Pop() - } - } else { - p.Log().Debug("Dropping transactions propagation", "count", len(txs)) - } -} - -// AsyncSendTransactionHashes queues list of transactions propagation to a remote -// peer. If the peer's broadcast queue is full, the transactions are silently dropped. -func (p *peer) AsyncSendTransactionHashes(txids []common.Hash, queue chan broadcastItem) { - if p.asyncSendNonEncodedItem(txids, NewEvmTxHashesMsg, queue) { - // Mark all the transactions as known, but ensure we don't overflow our limits - for _, tx := range txids { - p.knownTxs.Add(tx) - } - for p.knownTxs.Cardinality() >= p.cfg.MaxKnownTxs { - p.knownTxs.Pop() - } - } else { - p.Log().Debug("Dropping tx announcement", "count", len(txids)) - } -} - -// EnqueueSendTransactions queues list of transactions propagation to a remote -// peer. -// The method is blocking in a case if the peer's broadcast queue is full. -func (p *peer) EnqueueSendTransactions(txs types.Transactions, queue chan broadcastItem) { - p.enqueueSendNonEncodedItem(txs, EvmTxsMsg, queue) - // Mark all the transactions as known, but ensure we don't overflow our limits - for _, tx := range txs { - p.knownTxs.Add(tx.Hash()) - } - for p.knownTxs.Cardinality() >= p.cfg.MaxKnownTxs { - p.knownTxs.Pop() - } -} - -// SendEventIDs announces the availability of a number of events through -// a hash notification. -func (p *peer) SendEventIDs(hashes []hash.Event) error { - // Mark all the event hashes as known, but ensure we don't overflow our limits - for _, hash := range hashes { - p.knownEvents.Add(hash) - } - for p.knownEvents.Cardinality() >= p.cfg.MaxKnownEvents { - p.knownEvents.Pop() - } - return p2p.Send(p.rw, NewEventIDsMsg, hashes) -} - -// AsyncSendEventIDs queues the availability of a event for propagation to a -// remote peer. If the peer's broadcast queue is full, the event is silently -// dropped. -func (p *peer) AsyncSendEventIDs(ids hash.Events, queue chan broadcastItem) { - if p.asyncSendNonEncodedItem(ids, NewEventIDsMsg, queue) { - // Mark all the event hash as known, but ensure we don't overflow our limits - for _, id := range ids { - p.knownEvents.Add(id) - } - for p.knownEvents.Cardinality() >= p.cfg.MaxKnownEvents { - p.knownEvents.Pop() - } - } else { - p.Log().Debug("Dropping event announcement", "count", len(ids)) - } -} - -// SendEvents propagates a batch of events to a remote peer. -func (p *peer) SendEvents(events inter.EventPayloads) error { - // Mark all the event hash as known, but ensure we don't overflow our limits - for _, event := range events { - p.knownEvents.Add(event.ID()) - for p.knownEvents.Cardinality() >= p.cfg.MaxKnownEvents { - p.knownEvents.Pop() - } - } - return p2p.Send(p.rw, EventsMsg, events) -} - -// SendEventsRLP propagates a batch of RLP events to a remote peer. -func (p *peer) SendEventsRLP(events []rlp.RawValue, ids []hash.Event) error { - // Mark all the event hash as known, but ensure we don't overflow our limits - for _, id := range ids { - p.knownEvents.Add(id) - for p.knownEvents.Cardinality() >= p.cfg.MaxKnownEvents { - p.knownEvents.Pop() - } - } - return p2p.Send(p.rw, EventsMsg, events) -} - -// AsyncSendEvents queues an entire event for propagation to a remote peer. -// If the peer's broadcast queue is full, the events are silently dropped. -func (p *peer) AsyncSendEvents(events inter.EventPayloads, queue chan broadcastItem) bool { - if p.asyncSendNonEncodedItem(events, EventsMsg, queue) { - // Mark all the event hash as known, but ensure we don't overflow our limits - for _, event := range events { - p.knownEvents.Add(event.ID()) - } - for p.knownEvents.Cardinality() >= p.cfg.MaxKnownEvents { - p.knownEvents.Pop() - } - return true - } - p.Log().Debug("Dropping event propagation", "count", len(events)) - return false -} - -// EnqueueSendEventsRLP queues an entire RLP event for propagation to a remote peer. -// The method is blocking in a case if the peer's broadcast queue is full. -func (p *peer) EnqueueSendEventsRLP(events []rlp.RawValue, ids []hash.Event, queue chan broadcastItem) { - p.enqueueSendNonEncodedItem(events, EventsMsg, queue) - // Mark all the event hash as known, but ensure we don't overflow our limits - for _, id := range ids { - p.knownEvents.Add(id) - } - for p.knownEvents.Cardinality() >= p.cfg.MaxKnownEvents { - p.knownEvents.Pop() - } -} - -// AsyncSendProgress queues a progress propagation to a remote peer. -// If the peer's broadcast queue is full, the progress is silently dropped. -func (p *peer) AsyncSendProgress(progress PeerProgress, queue chan broadcastItem) { - if !p.asyncSendNonEncodedItem(progress, ProgressMsg, queue) { - p.Log().Debug("Dropping peer progress propagation") - } -} - -func (p *peer) RequestEvents(ids hash.Events) error { - // divide big batch into smaller ones - for start := 0; start < len(ids); start += softLimitItems { - end := len(ids) - if end > start+softLimitItems { - end = start + softLimitItems - } - p.Log().Debug("Fetching batch of events", "count", len(ids[start:end])) - err := p2p.Send(p.rw, GetEventsMsg, ids[start:end]) - if err != nil { - return err - } - } - return nil -} - -func (p *peer) RequestTransactions(txids []common.Hash) error { - // divide big batch into smaller ones - for start := 0; start < len(txids); start += softLimitItems { - end := len(txids) - if end > start+softLimitItems { - end = start + softLimitItems - } - p.Log().Debug("Fetching batch of transactions", "count", len(txids[start:end])) - err := p2p.Send(p.rw, GetEvmTxsMsg, txids[start:end]) - if err != nil { - return err - } - } - return nil -} - -func (p *peer) SendBVsStream(r bvstream.Response) error { - return p2p.Send(p.rw, BVsStreamResponse, r) -} - -func (p *peer) RequestBVsStream(r bvstream.Request) error { - return p2p.Send(p.rw, RequestBVsStream, r) -} - -func (p *peer) SendBRsStream(r brstream.Response) error { - return p2p.Send(p.rw, BRsStreamResponse, r) -} - -func (p *peer) RequestBRsStream(r brstream.Request) error { - return p2p.Send(p.rw, RequestBRsStream, r) -} - -func (p *peer) SendEPsStream(r epstream.Response) error { - return p2p.Send(p.rw, EPsStreamResponse, r) -} - -func (p *peer) RequestEPsStream(r epstream.Request) error { - return p2p.Send(p.rw, RequestEPsStream, r) -} - -func (p *peer) SendEventsStream(r dagstream.Response, ids hash.Events) error { - // Mark all the event hash as known, but ensure we don't overflow our limits - for _, id := range ids { - p.knownEvents.Add(id) - for p.knownEvents.Cardinality() >= p.cfg.MaxKnownEvents { - p.knownEvents.Pop() - } - } - return p2p.Send(p.rw, EventsStreamResponse, r) -} - -func (p *peer) RequestEventsStream(r dagstream.Request) error { - return p2p.Send(p.rw, RequestEventsStream, r) -} - -// Handshake executes the protocol handshake, negotiating version number, -// network IDs, difficulties, head and genesis object. -func (p *peer) Handshake(network uint64, progress PeerProgress, genesis common.Hash) error { - // Send out own handshake in a new thread - errc := make(chan error, 2) - var handshake handshakeData // safe to read after two values have been received from errc - - go func() { - // send both HandshakeMsg and ProgressMsg - err := p2p.Send(p.rw, HandshakeMsg, &handshakeData{ - ProtocolVersion: uint32(p.version), - NetworkID: 0, // TODO: set to `network` after all nodes updated to #184 - Genesis: genesis, - }) - if err != nil { - errc <- err - } - errc <- p.SendProgress(progress) - }() - go func() { - errc <- p.readStatus(network, &handshake, genesis) - // do not expect ProgressMsg here, because eth62 clients won't send it - }() - timeout := time.NewTimer(handshakeTimeout) - defer timeout.Stop() - for i := 0; i < 2; i++ { - select { - case err := <-errc: - if err != nil { - return err - } - case <-timeout.C: - return p2p.DiscReadTimeout - } - } - return nil -} - -func (p *peer) SendProgress(progress PeerProgress) error { - return p2p.Send(p.rw, ProgressMsg, progress) -} - -func (p *peer) readStatus(network uint64, handshake *handshakeData, genesis common.Hash) (err error) { - msg, err := p.rw.ReadMsg() - if err != nil { - return err - } - if msg.Code != HandshakeMsg { - return errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, HandshakeMsg) - } - if msg.Size > protocolMaxMsgSize { - return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, protocolMaxMsgSize) - } - // Decode the handshake and make sure everything matches - if err := msg.Decode(&handshake); err != nil { - return errResp(ErrDecode, "msg %v: %v", msg, err) - } - - // TODO: rm after all the nodes updated to #184 - if handshake.NetworkID == 0 { - handshake.NetworkID = network - } - - if handshake.Genesis != genesis { - return errResp(ErrGenesisMismatch, "%x (!= %x)", handshake.Genesis[:8], genesis[:8]) - } - if handshake.NetworkID != network { - return errResp(ErrNetworkIDMismatch, "%d (!= %d)", handshake.NetworkID, network) - } - if uint(handshake.ProtocolVersion) != p.version { - return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", handshake.ProtocolVersion, p.version) - } - return nil -} - -// String implements fmt.Stringer. -func (p *peer) String() string { - return fmt.Sprintf("Peer %s [%s]", p.id, - fmt.Sprintf("opera/%2d", p.version), - ) -} - -// snapPeerInfo represents a short summary of the `snap` sub-protocol metadata known -// about a connected peer. -type snapPeerInfo struct { - Version uint `json:"version"` // Snapshot protocol version negotiated -} - -// snapPeer is a wrapper around snap.Peer to maintain a few extra metadata. -type snapPeer struct { - *snap.Peer -} - -// info gathers and returns some `snap` protocol metadata known about a peer. -func (p *snapPeer) info() *snapPeerInfo { - return &snapPeerInfo{ - Version: p.Version(), - } -} - -// eligibleForSnap checks eligibility of a peer for a snap protocol. A peer is eligible for a snap if it advertises `snap` sattelite protocol along with `opera` protocol. -func eligibleForSnap(p *p2p.Peer) bool { - return p.RunningCap(ProtocolName, []uint{FTM63}) && p.RunningCap(snap.ProtocolName, snap.ProtocolVersions) -} diff --git a/evm/go-x1/gossip/peerset.go b/evm/go-x1/gossip/peerset.go deleted file mode 100644 index 2c6bc00..0000000 --- a/evm/go-x1/gossip/peerset.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package gossip - -import ( - "errors" - "sync" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/eth/protocols/snap" - "github.com/ethereum/go-ethereum/p2p" -) - -var ( - // errPeerSetClosed is returned if a peer is attempted to be added or removed - // from the peer set after it has been terminated. - errPeerSetClosed = errors.New("peerset closed") - - // errPeerAlreadyRegistered is returned if a peer is attempted to be added - // to the peer set, but one with the same id already exists. - errPeerAlreadyRegistered = errors.New("peer already registered") - - // errPeerNotRegistered is returned if a peer is attempted to be removed from - // a peer set, but no peer with the given id exists. - errPeerNotRegistered = errors.New("peer not registered") - - // errSnapWithoutOpera is returned if a peer attempts to connect only on the - // snap protocol without advertizing the opera main protocol. - errSnapWithoutOpera = errors.New("peer connected on snap without compatible opera support") -) - -// peerSet represents the collection of active peers currently participating in -// the `eth` protocol, with or without the `snap` extension. -type peerSet struct { - peers map[string]*peer // Peers connected on the `eth` protocol - snapPeers int // Number of `snap` compatible peers for connection prioritization - - snapWait map[string]chan *snap.Peer // Peers connected on `eth` waiting for their snap extension - snapPend map[string]*snap.Peer // Peers connected on the `snap` protocol, but not yet on `eth` - - lock sync.RWMutex - closed bool -} - -// newPeerSet creates a new peer set to track the active participants. -func newPeerSet() *peerSet { - return &peerSet{ - peers: make(map[string]*peer), - snapWait: make(map[string]chan *snap.Peer), - snapPend: make(map[string]*snap.Peer), - } -} - -// RegisterSnapExtension unblocks an already connected `eth` peer waiting for its -// `snap` extension, or if no such peer exists, tracks the extension for the time -// being until the `eth` main protocol starts looking for it. -func (ps *peerSet) RegisterSnapExtension(peer *snap.Peer) error { - // Reject the peer if it is not eligible for a snap protocol - if !eligibleForSnap(peer.Peer) { - return errSnapWithoutOpera - } - // Ensure nobody can double connect - ps.lock.Lock() - defer ps.lock.Unlock() - - id := peer.ID() - if _, ok := ps.peers[id]; ok { - return errPeerAlreadyRegistered // avoid connections with the same id as existing ones - } - if _, ok := ps.snapPend[id]; ok { - return errPeerAlreadyRegistered // avoid connections with the same id as pending ones - } - // Inject the peer into an `eth` counterpart is available, otherwise save for later - if wait, ok := ps.snapWait[id]; ok { - delete(ps.snapWait, id) - wait <- peer - return nil - } - ps.snapPend[id] = peer - return nil -} - -// WaitSnapExtension blocks until all satellite protocols are connected and tracked -// by the peerset. -func (ps *peerSet) WaitSnapExtension(p *peer) (*snap.Peer, error) { - // If the peer is not eligible for a snap protocol`, don't wait - if !eligibleForSnap(p.Peer) { - return nil, nil - } - // Ensure nobody can double connect - ps.lock.Lock() - - id := p.id - if _, ok := ps.peers[id]; ok { - ps.lock.Unlock() - return nil, errPeerAlreadyRegistered // avoid connections with the same id as existing ones - } - if _, ok := ps.snapWait[id]; ok { - ps.lock.Unlock() - return nil, errPeerAlreadyRegistered // avoid connections with the same id as pending ones - } - // If `snap` already connected, retrieve the peer from the pending set - if snap, ok := ps.snapPend[id]; ok { - delete(ps.snapPend, id) - - ps.lock.Unlock() - return snap, nil - } - // Otherwise wait for `snap` to connect concurrently - wait := make(chan *snap.Peer) - ps.snapWait[id] = wait - ps.lock.Unlock() - - return <-wait, nil -} - -// RegisterPeer injects a new `eth` peer into the working set, or returns an error -// if the peer is already known. -func (ps *peerSet) RegisterPeer(p *peer, ext *snap.Peer) error { - // Start tracking the new peer - ps.lock.Lock() - defer ps.lock.Unlock() - - if ps.closed { - return errPeerSetClosed - } - - id := p.id - if _, ok := ps.peers[id]; ok { - return errPeerAlreadyRegistered - } - - if ext != nil { - p.snapExt = &snapPeer{ext} - ps.snapPeers++ - } - - ps.peers[id] = p - return nil -} - -// UnregisterPeer removes a remote peer from the active set, disabling any further -// actions to/from that particular entity. -func (ps *peerSet) UnregisterPeer(id string) error { - ps.lock.Lock() - defer ps.lock.Unlock() - - peer, ok := ps.peers[id] - if !ok { - return errPeerNotRegistered - } - delete(ps.peers, id) - if peer.snapExt != nil { - ps.snapPeers-- - } - return nil -} - -// Peer retrieves the registered peer with the given id. -func (ps *peerSet) Peer(id string) *peer { - ps.lock.RLock() - defer ps.lock.RUnlock() - - return ps.peers[id] -} - -func (ps *peerSet) UselessNum() int { - ps.lock.RLock() - defer ps.lock.RUnlock() - - num := 0 - for _, p := range ps.peers { - if p.Useless() { - num++ - } - } - return num -} - -// PeersWithoutEvent retrieves a list of peers that do not have a given event in -// their set of known hashes so it might be propagated to them. -func (ps *peerSet) PeersWithoutEvent(e hash.Event) []*peer { - ps.lock.RLock() - defer ps.lock.RUnlock() - - list := make([]*peer, 0, len(ps.peers)) - for _, p := range ps.peers { - if p.InterestedIn(e) { - list = append(list, p) - } - } - return list -} - -// PeersWithoutTx retrieves a list of peers that do not have a given -// transaction in their set of known hashes. -func (ps *peerSet) PeersWithoutTx(hash common.Hash) []*peer { - ps.lock.RLock() - defer ps.lock.RUnlock() - - list := make([]*peer, 0, len(ps.peers)) - for _, p := range ps.peers { - if !p.knownTxs.Contains(hash) { - list = append(list, p) - } - } - return list -} - -// List returns array of peers in the set. -func (ps *peerSet) List() []*peer { - ps.lock.RLock() - defer ps.lock.RUnlock() - - list := make([]*peer, 0, len(ps.peers)) - for _, p := range ps.peers { - list = append(list, p) - } - return list -} - -// Len returns if the current number of `eth` peers in the set. Since the `snap` -// peers are tied to the existence of an `eth` connection, that will always be a -// subset of `eth`. -func (ps *peerSet) Len() int { - ps.lock.RLock() - defer ps.lock.RUnlock() - - return len(ps.peers) -} - -// SnapLen returns if the current number of `snap` peers in the set. -func (ps *peerSet) SnapLen() int { - ps.lock.RLock() - defer ps.lock.RUnlock() - - return ps.snapPeers -} - -// Close disconnects all peers. -func (ps *peerSet) Close() { - ps.lock.Lock() - defer ps.lock.Unlock() - - for _, p := range ps.peers { - p.Disconnect(p2p.DiscQuitting) - } - ps.closed = true -} diff --git a/evm/go-x1/gossip/proclogger/dag_logger.go b/evm/go-x1/gossip/proclogger/dag_logger.go deleted file mode 100644 index f4d26a1..0000000 --- a/evm/go-x1/gossip/proclogger/dag_logger.go +++ /dev/null @@ -1,46 +0,0 @@ -package proclogger - -import ( - "time" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/utils" -) - -func NewLogger() *Logger { - return &Logger{ - Instance: logger.New(), - } -} - -// EventConnectionStarted starts the event logging -// Not safe for concurrent use -func (l *Logger) EventConnectionStarted(e inter.EventPayloadI, emitted bool) func() { - l.dagSum.connected++ - - start := time.Now() - l.emitting = emitted - l.noSummary = true // print summary after the whole event is processed - l.lastID = e.ID() - l.lastEventTime = e.CreationTime() - - return func() { - now := time.Now() - // logging for the individual item - msg := "New event" - logType := l.Log.Debug - if emitted { - msg = "New event emitted" - logType = l.Log.Info - } - logType(msg, "id", e.ID(), "parents", len(e.Parents()), "by", e.Creator(), - "frame", e.Frame(), "txs", e.Txs().Len(), - "age", utils.PrettyDuration(now.Sub(e.CreationTime().Time())), "t", utils.PrettyDuration(now.Sub(start))) - // logging for the summary - l.dagSum.totalProcessing += now.Sub(start) - l.emitting = false - l.noSummary = false - l.summary(now) - } -} diff --git a/evm/go-x1/gossip/proclogger/llr_logger.go b/evm/go-x1/gossip/proclogger/llr_logger.go deleted file mode 100644 index 0b62d06..0000000 --- a/evm/go-x1/gossip/proclogger/llr_logger.go +++ /dev/null @@ -1,178 +0,0 @@ -package proclogger - -import ( - "fmt" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/utils" -) - -type dagSum struct { - connected idx.Event - totalProcessing time.Duration -} - -type llrSum struct { - bvs idx.Block - brs idx.Block - evs idx.Epoch - ers idx.Epoch -} - -type Logger struct { - // summary accumulators - dagSum dagSum - llrSum llrSum - - // latest logged data - lastEpoch idx.Epoch - lastBlock idx.Block - lastID hash.Event - lastEventTime inter.Timestamp - lastLlrTime inter.Timestamp - - nextLogging time.Time - - emitting bool - noSummary bool - - logger.Instance -} - -func (l *Logger) summary(now time.Time) { - if l.noSummary { - return - } - if now.After(l.nextLogging) { - if l.llrSum != (llrSum{}) { - age := utils.PrettyDuration(now.Sub(l.lastLlrTime.Time())).String() - if l.lastLlrTime <= l.lastEventTime { - age = "none" - } - l.Log.Info("New LLR summary", "last_epoch", l.lastEpoch, "last_block", l.lastBlock, - "new_evs", l.llrSum.evs, "new_ers", l.llrSum.ers, "new_bvs", l.llrSum.bvs, "new_brs", l.llrSum.brs, "age", age) - } - if l.dagSum != (dagSum{}) { - l.Log.Info("New DAG summary", "new", l.dagSum.connected, "last_id", l.lastID.String(), - "age", utils.PrettyDuration(now.Sub(l.lastEventTime.Time())), "t", utils.PrettyDuration(l.dagSum.totalProcessing)) - } - l.dagSum = dagSum{} - l.llrSum = llrSum{} - l.nextLogging = now.Add(8 * time.Second) - } -} - -// BlockVotesConnectionStarted starts the BVs logging -// Not safe for concurrent use -func (l *Logger) BlockVotesConnectionStarted(bvs inter.LlrSignedBlockVotes) func() { - if bvs.Val.Epoch == 0 { - return func() {} - } - l.llrSum.bvs += idx.Block(len(bvs.Val.Votes)) - - start := time.Now() - - return func() { - if l.lastBlock < bvs.Val.LastBlock() { - l.lastBlock = bvs.Val.LastBlock() - } - now := time.Now() - // logging for the individual item - msg := "New BVs" - logType := l.Log.Debug - if l.emitting { - msg = "New BVs emitted" - logType = l.Log.Info - } - logType(msg, "id", bvs.Signed.Locator.ID(), "by", bvs.Signed.Locator.Creator, - "blocks", fmt.Sprintf("%d-%d", bvs.Val.Start, bvs.Val.LastBlock()), - "t", utils.PrettyDuration(now.Sub(start))) - l.summary(now) - } -} - -// BlockRecordConnectionStarted starts the BR logging -// Not safe for concurrent use -func (l *Logger) BlockRecordConnectionStarted(br ibr.LlrIdxFullBlockRecord) func() { - l.llrSum.brs++ - - start := time.Now() - - return func() { - if l.lastBlock < br.Idx { - l.lastBlock = br.Idx - } - if l.lastLlrTime < br.Time { - l.lastLlrTime = br.Time - } - now := time.Now() - // logging for the individual item - msg := "New BR" - logType := l.Log.Debug - logType(msg, "block", br.Idx, - "age", utils.PrettyDuration(now.Sub(br.Time.Time())), - "t", utils.PrettyDuration(now.Sub(start))) - l.summary(now) - } -} - -// EpochVoteConnectionStarted starts the EV logging -// Not safe for concurrent use -func (l *Logger) EpochVoteConnectionStarted(ev inter.LlrSignedEpochVote) func() { - if ev.Val.Epoch == 0 { - return func() {} - } - l.llrSum.evs++ - - start := time.Now() - - return func() { - if l.lastEpoch < ev.Val.Epoch { - l.lastEpoch = ev.Val.Epoch - } - now := time.Now() - // logging for the individual item - msg := "New EV" - logType := l.Log.Debug - if l.emitting { - msg = "New EV emitted" - logType = l.Log.Info - } - logType(msg, "id", ev.Signed.Locator.ID(), "by", ev.Signed.Locator.Creator, - "epoch", ev.Val.Epoch, - "t", utils.PrettyDuration(now.Sub(start))) - l.summary(now) - } -} - -// EpochRecordConnectionStarted starts the ER logging -// Not safe for concurrent use -func (l *Logger) EpochRecordConnectionStarted(er ier.LlrIdxFullEpochRecord) func() { - l.llrSum.ers++ - - start := time.Now() - - return func() { - if l.lastEpoch < er.Idx { - l.lastEpoch = er.Idx - } - if l.lastLlrTime < er.EpochState.EpochStart { - l.lastLlrTime = er.EpochState.EpochStart - } - now := time.Now() - // logging for the individual item - msg := "New ER" - logType := l.Log.Debug - logType(msg, "epoch", er.Idx, - "age", utils.PrettyDuration(now.Sub(er.EpochState.EpochStart.Time())), - "t", utils.PrettyDuration(now.Sub(start))) - l.summary(now) - } -} diff --git a/evm/go-x1/gossip/protocol.go b/evm/go-x1/gossip/protocol.go deleted file mode 100644 index 5f3c46c..0000000 --- a/evm/go-x1/gossip/protocol.go +++ /dev/null @@ -1,163 +0,0 @@ -package gossip - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - notify "github.com/ethereum/go-ethereum/event" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/iep" -) - -// Constants to match up protocol versions and messages -const ( - FTM62 = 62 - FTM63 = 63 - ProtocolVersion = FTM63 -) - -// ProtocolName is the official short name of the protocol used during capability negotiation. -const ProtocolName = "opera" - -// ProtocolVersions are the supported versions of the protocol (first is primary). -var ProtocolVersions = []uint{FTM62, FTM63} - -// protocolLengths are the number of implemented message corresponding to different protocol versions. -var protocolLengths = map[uint]uint64{FTM62: EventsStreamResponse + 1, FTM63: EPsStreamResponse + 1} - -const protocolMaxMsgSize = inter.ProtocolMaxMsgSize // Maximum cap on the size of a protocol message - -// protocol message codes -const ( - HandshakeMsg = 0 - - // Signals about the current synchronization status. - // The current peer's status is used during packs downloading, - // and to estimate may peer be interested in the new event or not - // (based on peer's epoch). - ProgressMsg = 1 - - EvmTxsMsg = 2 - NewEvmTxHashesMsg = 3 - GetEvmTxsMsg = 4 - - // Non-aggressive events propagation. Signals about newly-connected - // batch of events, sending only their IDs. - NewEventIDsMsg = 5 - - // Request the batch of events by IDs - GetEventsMsg = 6 - // Contains the batch of events. - // May be an answer to GetEventsMsg, or be sent during aggressive events propagation. - EventsMsg = 7 - - // Request a range of events by a selector - RequestEventsStream = 8 - // Contains the requested events by RequestEventsStream - EventsStreamResponse = 9 - - RequestBVsStream = 10 - BVsStreamResponse = 11 - RequestBRsStream = 12 - BRsStreamResponse = 13 - RequestEPsStream = 14 - EPsStreamResponse = 15 -) - -type errCode int - -const ( - ErrMsgTooLarge = iota - ErrDecode - ErrInvalidMsgCode - ErrProtocolVersionMismatch - ErrNetworkIDMismatch - ErrGenesisMismatch - ErrNoStatusMsg - ErrExtraStatusMsg - ErrSuspendedPeer - ErrEmptyMessage = 0xf00 -) - -func (e errCode) String() string { - return errorToString[int(e)] -} - -// XXX change once legacy code is out -var errorToString = map[int]string{ - ErrMsgTooLarge: "Message too long", - ErrDecode: "Invalid message", - ErrInvalidMsgCode: "Invalid message code", - ErrProtocolVersionMismatch: "Protocol version mismatch", - ErrNetworkIDMismatch: "NetworkId mismatch", - ErrGenesisMismatch: "Genesis object mismatch", - ErrNoStatusMsg: "No status message", - ErrExtraStatusMsg: "Extra status message", - ErrSuspendedPeer: "Suspended peer", - ErrEmptyMessage: "Empty message", -} - -type TxPool interface { - emitter.TxPool - SubscribeNewTxsNotify(chan<- evmcore.NewTxsNotify) notify.Subscription - // AddRemotes should add the given transactions to the pool. - AddRemotes([]*types.Transaction) []error - AddLocals(txs []*types.Transaction) []error - AddLocal(tx *types.Transaction) error - - Get(common.Hash) *types.Transaction - - OnlyNotExisting(hashes []common.Hash) []common.Hash - SampleHashes(max int) []common.Hash - - Nonce(addr common.Address) uint64 - Stats() (int, int) - Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) - ContentFrom(addr common.Address) (types.Transactions, types.Transactions) -} - -// handshakeData is the network packet for the initial handshake message -type handshakeData struct { - ProtocolVersion uint32 - NetworkID uint64 - Genesis common.Hash -} - -// PeerProgress is synchronization status of a peer -type PeerProgress struct { - Epoch idx.Epoch - LastBlockIdx idx.Block - LastBlockAtropos hash.Event - // Currently unused - HighestLamport idx.Lamport -} - -type dagChunk struct { - SessionID uint32 - Done bool - IDs hash.Events - Events inter.EventPayloads -} - -type bvsChunk struct { - SessionID uint32 - Done bool - BVs []inter.LlrSignedBlockVotes -} - -type brsChunk struct { - SessionID uint32 - Done bool - BRs []ibr.LlrIdxFullBlockRecord -} - -type epsChunk struct { - SessionID uint32 - Done bool - EPs []iep.LlrEpochPack -} diff --git a/evm/go-x1/gossip/protocols/blockrecords/brprocessor/config.go b/evm/go-x1/gossip/protocols/blockrecords/brprocessor/config.go deleted file mode 100644 index b88e997..0000000 --- a/evm/go-x1/gossip/protocols/blockrecords/brprocessor/config.go +++ /dev/null @@ -1,29 +0,0 @@ -package brprocessor - -import ( - "time" - - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" -) - -type Config struct { - BufferLimit dag.Metric - - SemaphoreTimeout time.Duration - - MaxTasks int -} - -func DefaultConfig(scale cachescale.Func) Config { - return Config{ - BufferLimit: dag.Metric{ - Num: 10000, - Size: scale.U64(15 * opt.MiB), - }, - SemaphoreTimeout: 10 * time.Second, - MaxTasks: 512, - } -} diff --git a/evm/go-x1/gossip/protocols/blockrecords/brprocessor/processor.go b/evm/go-x1/gossip/protocols/blockrecords/brprocessor/processor.go deleted file mode 100644 index 5838cbf..0000000 --- a/evm/go-x1/gossip/protocols/blockrecords/brprocessor/processor.go +++ /dev/null @@ -1,95 +0,0 @@ -package brprocessor - -import ( - "errors" - "sync" - - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/datasemaphore" - "github.com/Fantom-foundation/lachesis-base/utils/workers" - - "github.com/Fantom-foundation/go-opera/inter/ibr" -) - -var ( - ErrBusy = errors.New("failed to acquire events semaphore") -) - -// Processor is responsible for processing incoming events -type Processor struct { - cfg Config - - quit chan struct{} - wg sync.WaitGroup - - callback Callback - - inserter *workers.Workers - - itemsSemaphore *datasemaphore.DataSemaphore -} - -type ItemCallback struct { - Process func(br ibr.LlrIdxFullBlockRecord) error - Released func(br ibr.LlrIdxFullBlockRecord, peer string, err error) -} - -type Callback struct { - Item ItemCallback -} - -// New creates an event processor -func New(itemsSemaphore *datasemaphore.DataSemaphore, cfg Config, callback Callback) *Processor { - f := &Processor{ - cfg: cfg, - quit: make(chan struct{}), - itemsSemaphore: itemsSemaphore, - } - f.callback = callback - f.inserter = workers.New(&f.wg, f.quit, cfg.MaxTasks) - return f -} - -// Start boots up the items processor. -func (f *Processor) Start() { - f.inserter.Start(1) -} - -// Stop interrupts the processor, canceling all the pending operations. -// Stop waits until all the internal goroutines have finished. -func (f *Processor) Stop() { - close(f.quit) - f.itemsSemaphore.Terminate() - f.wg.Wait() -} - -// Overloaded returns true if too much items are being processed -func (f *Processor) Overloaded() bool { - return f.inserter.TasksCount() > f.cfg.MaxTasks*3/4 -} - -func (f *Processor) Enqueue(peer string, items []ibr.LlrIdxFullBlockRecord, totalSize uint64, done func()) error { - metric := dag.Metric{Num: idx.Event(len(items)), Size: totalSize} - if !f.itemsSemaphore.Acquire(metric, f.cfg.SemaphoreTimeout) { - return ErrBusy - } - - return f.inserter.Enqueue(func() { - if done != nil { - defer done() - } - defer f.itemsSemaphore.Release(metric) - for i, item := range items { - // process item - err := f.callback.Item.Process(item) - items[i].Txs = nil - items[i].Receipts = nil - f.callback.Item.Released(item, peer, err) - } - }) -} - -func (f *Processor) TasksCount() int { - return f.inserter.TasksCount() -} diff --git a/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamleecher/config.go b/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamleecher/config.go deleted file mode 100644 index cb2d8f4..0000000 --- a/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamleecher/config.go +++ /dev/null @@ -1,42 +0,0 @@ -package brstreamleecher - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher/basepeerleecher" -) - -type Config struct { - Session basepeerleecher.EpochDownloaderConfig - RecheckInterval time.Duration - BaseProgressWatchdog time.Duration - BaseSessionWatchdog time.Duration - MinSessionRestart time.Duration - MaxSessionRestart time.Duration -} - -// DefaultConfig returns default leecher config -func DefaultConfig() Config { - return Config{ - Session: basepeerleecher.EpochDownloaderConfig{ - DefaultChunkItemsNum: 500, - DefaultChunkItemsSize: 512 * 1024, - ParallelChunksDownload: 6, - RecheckInterval: 10 * time.Millisecond, - }, - RecheckInterval: time.Second, - BaseProgressWatchdog: time.Second * 5, - BaseSessionWatchdog: time.Second * 30 * 5, - MinSessionRestart: time.Second * 5, - MaxSessionRestart: time.Minute * 5, - } -} - -// LiteConfig returns default leecher config for tests -func LiteConfig() Config { - cfg := DefaultConfig() - cfg.Session.DefaultChunkItemsSize /= 10 - cfg.Session.DefaultChunkItemsNum /= 10 - cfg.Session.ParallelChunksDownload = cfg.Session.ParallelChunksDownload/2 + 1 - return cfg -} diff --git a/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamleecher/leecher.go b/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamleecher/leecher.go deleted file mode 100644 index 4d5a71e..0000000 --- a/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamleecher/leecher.go +++ /dev/null @@ -1,218 +0,0 @@ -package brstreamleecher - -import ( - "math/rand" - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher" - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher/basepeerleecher" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brstream" -) - -// Leecher is responsible for requesting BRs based on lexicographic BRs streams -type Leecher struct { - *basestreamleecher.BaseLeecher - - // Callbacks - callback Callbacks - - cfg Config - - // State - session sessionState - - forceSyncing bool - paused bool -} - -// New creates an BRs downloader to request BRs based on lexicographic BRs streams -func New(cfg Config, callback Callbacks) *Leecher { - l := &Leecher{ - cfg: cfg, - callback: callback, - } - l.BaseLeecher = basestreamleecher.New(cfg.RecheckInterval, basestreamleecher.Callbacks{ - SelectSessionPeerCandidates: l.selectSessionPeerCandidates, - ShouldTerminateSession: l.shouldTerminateSession, - StartSession: l.startSession, - TerminateSession: l.terminateSession, - OngoingSession: func() bool { - return l.session.agent != nil - }, - OngoingSessionPeer: func() string { - return l.session.peer - }, - }) - return l -} - -type Callbacks struct { - LowestBlockToFill func() idx.Block - MaxBlockToFill func() idx.Block - IsProcessed func(lastBlock idx.Block) bool - - RequestChunk func(peer string, r brstream.Request) error - Suspend func(peer string) bool - PeerBlock func(peer string) idx.Block -} - -type sessionState struct { - agent *basepeerleecher.BasePeerLeecher - peer string - startTime time.Time - endTime time.Time - lastReceived time.Time - try uint32 - - sessionID uint32 - - lowestBlockToFill idx.Block -} - -func (d *Leecher) shouldTerminateSession() bool { - if d.paused || d.session.agent.Stopped() { - return true - } - - noProgress := time.Since(d.session.lastReceived) >= d.cfg.BaseProgressWatchdog*time.Duration(d.session.try+5)/5 - stuck := time.Since(d.session.startTime) >= d.cfg.BaseSessionWatchdog*time.Duration(d.session.try+5)/5 - return stuck || noProgress -} - -func (d *Leecher) terminateSession() { - // force the epoch download to end - if d.session.agent != nil { - d.session.agent.Terminate() - d.session.agent = nil - d.session.endTime = time.Now() - if d.callback.LowestBlockToFill() >= d.session.lowestBlockToFill+idx.Block(d.cfg.Session.DefaultChunkItemsNum) { - // reset the counter of unsuccessful sync attempts - d.session.try = 0 - } - } -} - -func (d *Leecher) Pause() { - d.Mu.Lock() - defer d.Mu.Unlock() - d.paused = true - d.terminateSession() -} - -func (d *Leecher) Resume() { - d.Mu.Lock() - defer d.Mu.Unlock() - d.paused = false -} - -func (d *Leecher) selectSessionPeerCandidates() []string { - if d.paused { - return nil - } - knowledgeablePeers := make([]string, 0, len(d.Peers)) - allPeers := make([]string, 0, len(d.Peers)) - start := d.callback.LowestBlockToFill() - if start >= d.callback.MaxBlockToFill() { - return nil - } - for p := range d.Peers { - block := d.callback.PeerBlock(p) - if block >= start { - knowledgeablePeers = append(knowledgeablePeers, p) - } - allPeers = append(allPeers, p) - } - sinceEnd := time.Since(d.session.endTime) - waitUntilProcessed := d.session.try == 0 || sinceEnd > d.cfg.MinSessionRestart - hasSomethingToSync := d.session.try == 0 || len(knowledgeablePeers) > 0 || sinceEnd >= d.cfg.MaxSessionRestart || d.forceSyncing - if waitUntilProcessed && hasSomethingToSync { - if len(knowledgeablePeers) > 0 && d.session.try%5 != 4 { - // normally work only with peers which have a higher block - return knowledgeablePeers - } else { - // if above doesn't work, try other peers on 5th try - return allPeers - } - } - return nil -} - -func getSessionID(block idx.Block, try uint32) uint32 { - return (uint32(block) << 12) ^ try -} - -func (d *Leecher) startSession(candidates []string) { - peer := candidates[rand.Intn(len(candidates))] - - start := d.callback.LowestBlockToFill() - end := d.callback.MaxBlockToFill() - if end <= start { - end = start + 1 - } - session := brstream.Session{ - ID: getSessionID(start, d.session.try), - Start: brstream.Locator(start), - Stop: brstream.Locator(end), - } - - d.session.agent = basepeerleecher.New(&d.Wg, d.cfg.Session, basepeerleecher.EpochDownloaderCallbacks{ - IsProcessed: func(id interface{}) bool { - lastBlock := id.(idx.Block) - return d.callback.IsProcessed(lastBlock) - }, - RequestChunks: func(maxNum uint32, maxSize uint64, chunks uint32) error { - return d.callback.RequestChunk(peer, - brstream.Request{ - Session: session, - Limit: brstream.Metric{Num: idx.Block(maxNum), Size: maxSize}, - Type: 0, - MaxChunks: chunks, - }) - }, - Suspend: func() bool { - return d.callback.Suspend(peer) - }, - Done: func() bool { - return false - }, - }) - - now := time.Now() - d.session.startTime = now - d.session.lastReceived = now - d.session.endTime = now - d.session.try++ - d.session.peer = peer - d.session.sessionID = session.ID - d.session.lowestBlockToFill = start - - d.session.agent.Start() - - d.forceSyncing = false -} - -func (d *Leecher) ForceSyncing() { - d.Mu.Lock() - defer d.Mu.Unlock() - d.forceSyncing = true -} - -func (d *Leecher) NotifyChunkReceived(sessionID uint32, lastBlock idx.Block, done bool) error { - d.Mu.Lock() - defer d.Mu.Unlock() - if d.session.agent == nil { - return nil - } - if d.session.sessionID != sessionID { - return nil - } - - d.session.lastReceived = time.Now() - if done { - d.terminateSession() - return nil - } - return d.session.agent.NotifyChunkReceived(lastBlock) -} diff --git a/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamseeder/config.go b/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamseeder/config.go deleted file mode 100644 index 98aaf8c..0000000 --- a/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamseeder/config.go +++ /dev/null @@ -1,19 +0,0 @@ -package brstreamseeder - -import ( - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamseeder" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" -) - -type Config basestreamseeder.Config - -func DefaultConfig(scale cachescale.Func) Config { - return Config{ - SenderThreads: 2, - MaxSenderTasks: 64, - MaxPendingResponsesSize: scale.I64(32 * 1024 * 1024), - MaxResponsePayloadNum: 4096, - MaxResponsePayloadSize: 8 * 1024 * 1024, - MaxResponseChunks: 12, - } -} diff --git a/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamseeder/seeder.go b/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamseeder/seeder.go deleted file mode 100644 index 8fa2f93..0000000 --- a/evm/go-x1/gossip/protocols/blockrecords/brstream/brstreamseeder/seeder.go +++ /dev/null @@ -1,82 +0,0 @@ -package brstreamseeder - -import ( - "errors" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream" - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamseeder" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockrecords/brstream" -) - -var ( - ErrWrongType = errors.New("wrong request type") -) - -type Seeder struct { - *basestreamseeder.BaseSeeder -} - -type Callbacks struct { - Iterate func(start idx.Block, f func(block idx.Block, brs rlp.RawValue) bool) -} - -type Peer struct { - ID string - SendChunk func(brstream.Response) error - Misbehaviour func(error) -} - -func New(cfg Config, callbacks Callbacks) *Seeder { - return &Seeder{ - BaseSeeder: basestreamseeder.New(basestreamseeder.Config(cfg), basestreamseeder.Callbacks{ - ForEachItem: func(start basestream.Locator, _ basestream.RequestType, onKey func(key basestream.Locator) bool, onAppended func(items basestream.Payload) bool) basestream.Payload { - res := &brstream.Payload{ - Items: []rlp.RawValue{}, - Keys: []brstream.Locator{}, - Size: 0, - } - st := start.(brstream.Locator) - callbacks.Iterate(idx.Block(st), func(block idx.Block, brs rlp.RawValue) bool { - key := brstream.Locator(block) - if !onKey(key) { - return false - } - res.AddFullBlockRecords(key, brs) - return onAppended(res) - }) - return res - }, - }), - } -} - -func (s *Seeder) NotifyRequestReceived(peer Peer, r brstream.Request) (err error, peerErr error) { - if r.Type != 0 { - return nil, ErrWrongType - } - return s.BaseSeeder.NotifyRequestReceived(basestreamseeder.Peer{ - ID: peer.ID, - SendChunk: func(response basestream.Response) error { - return peer.SendChunk(brstream.Response{ - SessionID: response.SessionID, - Done: response.Done, - Payload: response.Payload.(*brstream.Payload).Items, - }) - }, - Misbehaviour: peer.Misbehaviour, - }, basestream.Request{ - Session: basestream.Session{ - ID: r.Session.ID, - Start: r.Session.Start, - Stop: r.Session.Stop, - }, - Type: r.Type, - MaxPayloadNum: uint32(r.Limit.Num), - MaxPayloadSize: r.Limit.Size, - MaxChunks: r.MaxChunks, - }) -} diff --git a/evm/go-x1/gossip/protocols/blockrecords/brstream/types.go b/evm/go-x1/gossip/protocols/blockrecords/brstream/types.go deleted file mode 100644 index 242b7e5..0000000 --- a/evm/go-x1/gossip/protocols/blockrecords/brstream/types.go +++ /dev/null @@ -1,78 +0,0 @@ -package brstream - -import ( - "fmt" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream" -) - -type Request struct { - Session Session - Limit Metric - Type basestream.RequestType - MaxChunks uint32 -} - -type Response struct { - SessionID uint32 - Done bool - Payload []rlp.RawValue -} - -type Session struct { - ID uint32 - Start Locator - Stop Locator -} - -type Locator idx.Block - -func (l Locator) Compare(b basestream.Locator) int { - if l == b.(Locator) { - return 0 - } - if l < b.(Locator) { - return -1 - } - return 1 -} - -func (l Locator) Inc() basestream.Locator { - return l + 1 -} - -type Payload struct { - Items []rlp.RawValue - Keys []Locator - Size uint64 -} - -func (p *Payload) AddFullBlockRecords(id Locator, brsB rlp.RawValue) { - p.Items = append(p.Items, brsB) - p.Keys = append(p.Keys, id) - p.Size += uint64(len(brsB)) -} - -func (p Payload) Len() int { - return len(p.Keys) -} - -func (p Payload) TotalSize() uint64 { - return p.Size -} - -func (p Payload) TotalMemSize() int { - return int(p.Size) + len(p.Keys)*32 -} - -type Metric struct { - Num idx.Block - Size uint64 -} - -func (m Metric) String() string { - return fmt.Sprintf("{Num=%d,Size=%d}", m.Num, m.Size) -} diff --git a/evm/go-x1/gossip/protocols/blockvotes/bvprocessor/config.go b/evm/go-x1/gossip/protocols/blockvotes/bvprocessor/config.go deleted file mode 100644 index 1b24a33..0000000 --- a/evm/go-x1/gossip/protocols/blockvotes/bvprocessor/config.go +++ /dev/null @@ -1,29 +0,0 @@ -package bvprocessor - -import ( - "time" - - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" -) - -type Config struct { - BufferLimit dag.Metric - - SemaphoreTimeout time.Duration - - MaxTasks int -} - -func DefaultConfig(scale cachescale.Func) Config { - return Config{ - BufferLimit: dag.Metric{ - Num: 3000, - Size: scale.U64(15 * opt.MiB), - }, - SemaphoreTimeout: 10 * time.Second, - MaxTasks: 512, - } -} diff --git a/evm/go-x1/gossip/protocols/blockvotes/bvprocessor/processor.go b/evm/go-x1/gossip/protocols/blockvotes/bvprocessor/processor.go deleted file mode 100644 index b60280d..0000000 --- a/evm/go-x1/gossip/protocols/blockvotes/bvprocessor/processor.go +++ /dev/null @@ -1,155 +0,0 @@ -package bvprocessor - -import ( - "errors" - "sync" - - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/datasemaphore" - "github.com/Fantom-foundation/lachesis-base/utils/workers" - - "github.com/Fantom-foundation/go-opera/inter" -) - -var ( - ErrBusy = errors.New("failed to acquire events semaphore") -) - -// Processor is responsible for processing incoming events -type Processor struct { - cfg Config - - quit chan struct{} - wg sync.WaitGroup - - callback Callback - - inserter *workers.Workers - - checker *workers.Workers - - itemsSemaphore *datasemaphore.DataSemaphore -} - -type ItemCallback struct { - Process func(bvs inter.LlrSignedBlockVotes) error - Released func(bvs inter.LlrSignedBlockVotes, peer string, err error) - Check func(bvs inter.LlrSignedBlockVotes, checked func(error)) -} - -type Callback struct { - Item ItemCallback -} - -// New creates an event processor -func New(itemsSemaphore *datasemaphore.DataSemaphore, cfg Config, callback Callback) *Processor { - f := &Processor{ - cfg: cfg, - quit: make(chan struct{}), - itemsSemaphore: itemsSemaphore, - } - released := callback.Item.Released - callback.Item.Released = func(bvs inter.LlrSignedBlockVotes, peer string, err error) { - f.itemsSemaphore.Release(dag.Metric{Num: 1, Size: uint64(bvs.Size())}) - if released != nil { - released(bvs, peer, err) - } - } - f.callback = callback - f.inserter = workers.New(&f.wg, f.quit, cfg.MaxTasks) - f.checker = workers.New(&f.wg, f.quit, cfg.MaxTasks) - return f -} - -// Start boots up the items processor. -func (f *Processor) Start() { - f.inserter.Start(1) - f.checker.Start(1) -} - -// Stop interrupts the processor, canceling all the pending operations. -// Stop waits until all the internal goroutines have finished. -func (f *Processor) Stop() { - close(f.quit) - f.itemsSemaphore.Terminate() - f.wg.Wait() -} - -// Overloaded returns true if too much items are being processed -func (f *Processor) Overloaded() bool { - return f.TasksCount() > f.cfg.MaxTasks*3/4 -} - -type checkRes struct { - bvs inter.LlrSignedBlockVotes - err error - pos idx.Event -} - -func (f *Processor) Enqueue(peer string, items []inter.LlrSignedBlockVotes, done func()) error { - totalSize := uint64(0) - for _, v := range items { - totalSize += v.Size() - } - if !f.itemsSemaphore.Acquire(dag.Metric{Num: idx.Event(len(items)), Size: totalSize}, f.cfg.SemaphoreTimeout) { - return ErrBusy - } - - checkedC := make(chan *checkRes, len(items)) - err := f.checker.Enqueue(func() { - for i, v := range items { - pos := idx.Event(i) - bvs := v - f.callback.Item.Check(bvs, func(err error) { - checkedC <- &checkRes{ - bvs: bvs, - err: err, - pos: pos, - } - }) - } - }) - if err != nil { - return err - } - itemsLen := len(items) - return f.inserter.Enqueue(func() { - if done != nil { - defer done() - } - - var orderedResults = make([]*checkRes, itemsLen) - var processed int - for processed < itemsLen { - select { - case res := <-checkedC: - orderedResults[res.pos] = res - - for i := processed; processed < len(orderedResults) && orderedResults[i] != nil; i++ { - f.process(peer, orderedResults[i].bvs, orderedResults[i].err) - orderedResults[i] = nil // free the memory - processed++ - } - - case <-f.quit: - return - } - } - }) -} - -func (f *Processor) process(peer string, bvs inter.LlrSignedBlockVotes, resErr error) { - // release item if failed validation - if resErr != nil { - f.callback.Item.Released(bvs, peer, resErr) - return - } - // process item - err := f.callback.Item.Process(bvs) - f.callback.Item.Released(bvs, peer, err) -} - -func (f *Processor) TasksCount() int { - return f.inserter.TasksCount() + f.checker.TasksCount() -} diff --git a/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamleecher/config.go b/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamleecher/config.go deleted file mode 100644 index 3009ef2..0000000 --- a/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamleecher/config.go +++ /dev/null @@ -1,42 +0,0 @@ -package bvstreamleecher - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher/basepeerleecher" -) - -type Config struct { - Session basepeerleecher.EpochDownloaderConfig - RecheckInterval time.Duration - BaseProgressWatchdog time.Duration - BaseSessionWatchdog time.Duration - MinSessionRestart time.Duration - MaxSessionRestart time.Duration -} - -// DefaultConfig returns default leecher config -func DefaultConfig() Config { - return Config{ - Session: basepeerleecher.EpochDownloaderConfig{ - DefaultChunkItemsNum: 500, - DefaultChunkItemsSize: 512 * 1024, - ParallelChunksDownload: 6, - RecheckInterval: 10 * time.Millisecond, - }, - RecheckInterval: time.Second, - BaseProgressWatchdog: time.Second * 5, - BaseSessionWatchdog: time.Second * 30 * 5, - MinSessionRestart: time.Second * 5, - MaxSessionRestart: time.Minute * 5, - } -} - -// LiteConfig returns default leecher config for tests -func LiteConfig() Config { - cfg := DefaultConfig() - cfg.Session.DefaultChunkItemsSize /= 10 - cfg.Session.DefaultChunkItemsNum /= 10 - cfg.Session.ParallelChunksDownload = cfg.Session.ParallelChunksDownload/2 + 1 - return cfg -} diff --git a/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamleecher/leecher.go b/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamleecher/leecher.go deleted file mode 100644 index b6c8850..0000000 --- a/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamleecher/leecher.go +++ /dev/null @@ -1,210 +0,0 @@ -package bvstreamleecher - -import ( - "math/rand" - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher" - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher/basepeerleecher" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvstream" -) - -// Leecher is responsible for requesting BVs based on lexicographic BVs streams -type Leecher struct { - *basestreamleecher.BaseLeecher - - // Callbacks - callback Callbacks - - cfg Config - - // State - session sessionState - - forceSyncing bool -} - -// New creates an BVs downloader to request BVs based on lexicographic BVs streams -func New(cfg Config, callback Callbacks) *Leecher { - l := &Leecher{ - cfg: cfg, - callback: callback, - } - l.BaseLeecher = basestreamleecher.New(cfg.RecheckInterval, basestreamleecher.Callbacks{ - SelectSessionPeerCandidates: l.selectSessionPeerCandidates, - ShouldTerminateSession: l.shouldTerminateSession, - StartSession: l.startSession, - TerminateSession: l.terminateSession, - OngoingSession: func() bool { - return l.session.agent != nil - }, - OngoingSessionPeer: func() string { - return l.session.peer - }, - }) - return l -} - -type Callbacks struct { - LowestBlockToDecide func() (idx.Epoch, idx.Block) - MaxEpochToDecide func() idx.Epoch - IsProcessed func(epoch idx.Epoch, lastBlock idx.Block, id hash.Event) bool - - RequestChunk func(peer string, r bvstream.Request) error - Suspend func(peer string) bool - PeerBlock func(peer string) idx.Block -} - -type sessionState struct { - agent *basepeerleecher.BasePeerLeecher - peer string - startTime time.Time - endTime time.Time - lastReceived time.Time - try uint32 - - sessionID uint32 - - lowestBlockToDecide idx.Block -} - -type BVsID struct { - Epoch idx.Epoch - LastBlock idx.Block - ID hash.Event -} - -func (d *Leecher) shouldTerminateSession() bool { - if d.session.agent.Stopped() { - return true - } - - noProgress := time.Since(d.session.lastReceived) >= d.cfg.BaseProgressWatchdog*time.Duration(d.session.try+5)/5 - stuck := time.Since(d.session.startTime) >= d.cfg.BaseSessionWatchdog*time.Duration(d.session.try+5)/5 - return stuck || noProgress -} - -func (d *Leecher) terminateSession() { - // force the epoch download to end - if d.session.agent != nil { - d.session.agent.Terminate() - d.session.agent = nil - d.session.endTime = time.Now() - _, lowestBlockToDecide := d.callback.LowestBlockToDecide() - if lowestBlockToDecide >= d.session.lowestBlockToDecide+idx.Block(d.cfg.Session.DefaultChunkItemsNum) { - // reset the counter of unsuccessful sync attempts - d.session.try = 0 - } - } -} - -func (d *Leecher) selectSessionPeerCandidates() []string { - knowledgeablePeers := make([]string, 0, len(d.Peers)) - allPeers := make([]string, 0, len(d.Peers)) - startEpoch, startBlock := d.callback.LowestBlockToDecide() - endEpoch := d.callback.MaxEpochToDecide() - if startEpoch >= endEpoch { - return nil - } - for p := range d.Peers { - block := d.callback.PeerBlock(p) - if block >= startBlock { - knowledgeablePeers = append(knowledgeablePeers, p) - } - allPeers = append(allPeers, p) - } - sinceEnd := time.Since(d.session.endTime) - waitUntilProcessed := d.session.try == 0 || sinceEnd > d.cfg.MinSessionRestart - hasSomethingToSync := d.session.try == 0 || len(knowledgeablePeers) > 0 || sinceEnd >= d.cfg.MaxSessionRestart || d.forceSyncing - if waitUntilProcessed && hasSomethingToSync { - if len(knowledgeablePeers) > 0 && d.session.try%5 != 4 { - // normally work only with peers which have a higher block - return knowledgeablePeers - } else { - // if above doesn't work, try other peers on 5th try - return allPeers - } - } - return nil -} - -func getSessionID(block idx.Block, try uint32) uint32 { - return (uint32(block) << 12) ^ try -} - -func (d *Leecher) startSession(candidates []string) { - peer := candidates[rand.Intn(len(candidates))] - - startEpoch, startBlock := d.callback.LowestBlockToDecide() - endEpoch := d.callback.MaxEpochToDecide() - if endEpoch <= startEpoch { - endEpoch = startEpoch + 1 - } - session := bvstream.Session{ - ID: getSessionID(startBlock, d.session.try), - Start: bvstream.Locator(append(startEpoch.Bytes(), startBlock.Bytes()...)), - Stop: bvstream.Locator(endEpoch.Bytes()), - } - - d.session.agent = basepeerleecher.New(&d.Wg, d.cfg.Session, basepeerleecher.EpochDownloaderCallbacks{ - IsProcessed: func(id interface{}) bool { - lastID := id.(BVsID) - return d.callback.IsProcessed(lastID.Epoch, lastID.LastBlock, lastID.ID) - }, - RequestChunks: func(maxNum uint32, maxSize uint64, chunks uint32) error { - return d.callback.RequestChunk(peer, - bvstream.Request{ - Session: session, - Limit: bvstream.Metric{Num: idx.Block(maxNum), Size: maxSize}, - Type: 0, - MaxChunks: chunks, - }) - }, - Suspend: func() bool { - return d.callback.Suspend(peer) - }, - Done: func() bool { - return false - }, - }) - - now := time.Now() - d.session.startTime = now - d.session.lastReceived = now - d.session.endTime = now - d.session.try++ - d.session.peer = peer - d.session.sessionID = session.ID - d.session.lowestBlockToDecide = startBlock - - d.session.agent.Start() - - d.forceSyncing = false -} - -func (d *Leecher) ForceSyncing() { - d.Mu.Lock() - defer d.Mu.Unlock() - d.forceSyncing = true -} - -func (d *Leecher) NotifyChunkReceived(sessionID uint32, lastID BVsID, done bool) error { - d.Mu.Lock() - defer d.Mu.Unlock() - if d.session.agent == nil { - return nil - } - if d.session.sessionID != sessionID { - return nil - } - - d.session.lastReceived = time.Now() - if done { - d.terminateSession() - return nil - } - return d.session.agent.NotifyChunkReceived(lastID) -} diff --git a/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamseeder/config.go b/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamseeder/config.go deleted file mode 100644 index 28742f2..0000000 --- a/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamseeder/config.go +++ /dev/null @@ -1,19 +0,0 @@ -package bvstreamseeder - -import ( - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamseeder" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" -) - -type Config basestreamseeder.Config - -func DefaultConfig(scale cachescale.Func) Config { - return Config{ - SenderThreads: 2, - MaxSenderTasks: 64, - MaxPendingResponsesSize: scale.I64(32 * 1024 * 1024), - MaxResponsePayloadNum: 4096, - MaxResponsePayloadSize: 8 * 1024 * 1024, - MaxResponseChunks: 12, - } -} diff --git a/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamseeder/seeder.go b/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamseeder/seeder.go deleted file mode 100644 index 0f91053..0000000 --- a/evm/go-x1/gossip/protocols/blockvotes/bvstream/bvstreamseeder/seeder.go +++ /dev/null @@ -1,86 +0,0 @@ -package bvstreamseeder - -import ( - "errors" - - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream" - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamseeder" - "github.com/Fantom-foundation/lachesis-base/hash" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/blockvotes/bvstream" -) - -var ( - ErrWrongType = errors.New("wrong request type") - ErrWrongSelectorLen = errors.New("wrong event selector length") -) - -type Seeder struct { - *basestreamseeder.BaseSeeder -} - -type Callbacks struct { - Iterate func(locator []byte, f func(key []byte, bvs rlp.RawValue) bool) -} - -type Peer struct { - ID string - SendChunk func(bvstream.Response) error - Misbehaviour func(error) -} - -func New(cfg Config, callbacks Callbacks) *Seeder { - return &Seeder{ - BaseSeeder: basestreamseeder.New(basestreamseeder.Config(cfg), basestreamseeder.Callbacks{ - ForEachItem: func(start basestream.Locator, _ basestream.RequestType, onKey func(key basestream.Locator) bool, onAppended func(items basestream.Payload) bool) basestream.Payload { - res := &bvstream.Payload{ - Items: []rlp.RawValue{}, - Keys: []bvstream.Locator{}, - Size: 0, - } - st := start.(bvstream.Locator) - callbacks.Iterate(st, func(bkey []byte, bvs rlp.RawValue) bool { - key := bvstream.Locator(bkey) - if !onKey(key) { - return false - } - res.AddSignedBlockVotes(key, bvs) - return onAppended(res) - }) - return res - }, - }), - } -} - -func (s *Seeder) NotifyRequestReceived(peer Peer, r bvstream.Request) (err error, peerErr error) { - if len(r.Session.Start) > len(hash.ZeroEvent)+4+8 || len(r.Session.Stop) > len(hash.ZeroEvent)+4+8 { - return nil, ErrWrongSelectorLen - } - if r.Type != 0 { - return nil, ErrWrongType - } - return s.BaseSeeder.NotifyRequestReceived(basestreamseeder.Peer{ - ID: peer.ID, - SendChunk: func(response basestream.Response) error { - return peer.SendChunk(bvstream.Response{ - SessionID: response.SessionID, - Done: response.Done, - Payload: response.Payload.(*bvstream.Payload).Items, - }) - }, - Misbehaviour: peer.Misbehaviour, - }, basestream.Request{ - Session: basestream.Session{ - ID: r.Session.ID, - Start: r.Session.Start, - Stop: r.Session.Stop, - }, - Type: r.Type, - MaxPayloadNum: uint32(r.Limit.Num), - MaxPayloadSize: r.Limit.Size, - MaxChunks: r.MaxChunks, - }) -} diff --git a/evm/go-x1/gossip/protocols/blockvotes/bvstream/types.go b/evm/go-x1/gossip/protocols/blockvotes/bvstream/types.go deleted file mode 100644 index 38ea04e..0000000 --- a/evm/go-x1/gossip/protocols/blockvotes/bvstream/types.go +++ /dev/null @@ -1,77 +0,0 @@ -package bvstream - -import ( - "bytes" - "fmt" - "math/big" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream" -) - -type Request struct { - Session Session - Limit Metric - Type basestream.RequestType - MaxChunks uint32 -} - -type Response struct { - SessionID uint32 - Done bool - Payload []rlp.RawValue -} - -type Session struct { - ID uint32 - Start Locator - Stop Locator -} - -type Locator []byte - -func (l Locator) Compare(b basestream.Locator) int { - return bytes.Compare(l, b.(Locator)) -} - -func (l Locator) Inc() basestream.Locator { - nextBn := new(big.Int).SetBytes(l) - nextBn.Add(nextBn, common.Big1) - return Locator(common.LeftPadBytes(nextBn.Bytes(), len(l))) -} - -type Payload struct { - Items []rlp.RawValue - Keys []Locator - Size uint64 -} - -func (p *Payload) AddSignedBlockVotes(id Locator, bvsB rlp.RawValue) { - p.Items = append(p.Items, bvsB) - p.Keys = append(p.Keys, id) - p.Size += uint64(len(bvsB)) -} - -func (p Payload) Len() int { - return len(p.Keys) -} - -func (p Payload) TotalSize() uint64 { - return p.Size -} - -func (p Payload) TotalMemSize() int { - return int(p.Size) + len(p.Keys)*128 -} - -type Metric struct { - Num idx.Block - Size uint64 -} - -func (m Metric) String() string { - return fmt.Sprintf("{Num=%d,Size=%d}", m.Num, m.Size) -} diff --git a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/config.go b/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/config.go deleted file mode 100644 index 82427c8..0000000 --- a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/config.go +++ /dev/null @@ -1,42 +0,0 @@ -package dagstreamleecher - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher/basepeerleecher" -) - -type Config struct { - Session basepeerleecher.EpochDownloaderConfig - RecheckInterval time.Duration - BaseProgressWatchdog time.Duration - BaseSessionWatchdog time.Duration - MinSessionRestart time.Duration - MaxSessionRestart time.Duration -} - -// DefaultConfig returns default leecher config -func DefaultConfig() Config { - return Config{ - Session: basepeerleecher.EpochDownloaderConfig{ - DefaultChunkItemsNum: 500, - DefaultChunkItemsSize: 512 * 1024, - ParallelChunksDownload: 6, - RecheckInterval: 10 * time.Millisecond, - }, - RecheckInterval: time.Second, - BaseProgressWatchdog: time.Second * 5, - BaseSessionWatchdog: time.Second * 30 * 5, - MinSessionRestart: time.Second * 5, - MaxSessionRestart: time.Minute * 5, - } -} - -// LiteConfig returns default leecher config for tests -func LiteConfig() Config { - cfg := DefaultConfig() - cfg.Session.DefaultChunkItemsSize /= 10 - cfg.Session.DefaultChunkItemsNum /= 10 - cfg.Session.ParallelChunksDownload = cfg.Session.ParallelChunksDownload/2 + 1 - return cfg -} diff --git a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/leecher.go b/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/leecher.go deleted file mode 100644 index 617881c..0000000 --- a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/leecher.go +++ /dev/null @@ -1,227 +0,0 @@ -package dagstreamleecher - -import ( - "math/rand" - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher" - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher/basepeerleecher" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/dag/dagstream" -) - -// Leecher is responsible for requesting events based on lexicographic event streams -type Leecher struct { - *basestreamleecher.BaseLeecher - - // Callbacks - callback Callbacks - - cfg Config - - // State - session sessionState - epoch idx.Epoch - - emptyState bool - forceSyncing bool - paused bool -} - -// New creates an events downloader to request events based on lexicographic event streams -func New(epoch idx.Epoch, emptyState bool, cfg Config, callback Callbacks) *Leecher { - l := &Leecher{ - cfg: cfg, - callback: callback, - emptyState: emptyState, - epoch: epoch, - } - l.BaseLeecher = basestreamleecher.New(cfg.RecheckInterval, basestreamleecher.Callbacks{ - SelectSessionPeerCandidates: l.selectSessionPeerCandidates, - ShouldTerminateSession: l.shouldTerminateSession, - StartSession: l.startSession, - TerminateSession: l.terminateSession, - OngoingSession: func() bool { - return l.session.agent != nil - }, - OngoingSessionPeer: func() string { - return l.session.peer - }, - }) - return l -} - -type Callbacks struct { - IsProcessed func(hash.Event) bool - - RequestChunk func(peer string, r dagstream.Request) error - Suspend func(peer string) bool - PeerEpoch func(peer string) idx.Epoch -} - -type sessionState struct { - agent *basepeerleecher.BasePeerLeecher - peer string - startTime time.Time - endTime time.Time - lastReceived time.Time - try uint32 -} - -func (d *Leecher) shouldTerminateSession() bool { - if d.paused || d.session.agent.Stopped() { - return true - } - - noProgress := time.Since(d.session.lastReceived) >= d.cfg.BaseProgressWatchdog*time.Duration(d.session.try+5)/5 - stuck := time.Since(d.session.startTime) >= d.cfg.BaseSessionWatchdog*time.Duration(d.session.try+5)/5 - return stuck || noProgress -} - -func (d *Leecher) terminateSession() { - // force the epoch download to end - if d.session.agent != nil { - d.session.agent.Terminate() - d.session.agent = nil - d.session.endTime = time.Now() - } -} - -func (d *Leecher) Pause() { - d.Mu.Lock() - defer d.Mu.Unlock() - d.paused = true - d.terminateSession() -} - -func (d *Leecher) Resume() { - d.Mu.Lock() - defer d.Mu.Unlock() - d.paused = false -} - -func (d *Leecher) selectSessionPeerCandidates() []string { - if d.paused { - return nil - } - var selected []string - currentEpochPeers := make([]string, 0, len(d.Peers)) - futureEpochPeers := make([]string, 0, len(d.Peers)) - for p := range d.Peers { - epoch := d.callback.PeerEpoch(p) - if epoch == d.epoch { - currentEpochPeers = append(currentEpochPeers, p) - } - if epoch > d.epoch { - futureEpochPeers = append(futureEpochPeers, p) - } - } - sinceEnd := time.Since(d.session.endTime) - waitUntilProcessed := d.session.try == 0 || sinceEnd > d.cfg.MinSessionRestart - hasSomethingToSync := d.session.try == 0 || len(futureEpochPeers) > 0 || sinceEnd >= d.cfg.MaxSessionRestart || d.forceSyncing - if waitUntilProcessed && hasSomethingToSync { - if len(futureEpochPeers) > 0 && (d.session.try%5 != 4 || len(currentEpochPeers) == 0) { - // normally work only with peers which have a higher epoch - selected = futureEpochPeers - } else { - // if above doesn't work, try peers on current epoch every 5th try - selected = currentEpochPeers - } - } - return selected -} - -func getSessionID(epoch idx.Epoch, try uint32) uint32 { - return (uint32(epoch) << 12) ^ try -} - -func (d *Leecher) startSession(candidates []string) { - peer := candidates[rand.Intn(len(candidates))] - - typ := dagstream.RequestIDs - if d.callback.PeerEpoch(peer) > d.epoch && d.emptyState && d.session.try == 0 { - typ = dagstream.RequestEvents - } - - session := dagstream.Session{ - ID: getSessionID(d.epoch, d.session.try), - Start: d.epoch.Bytes(), - Stop: (d.epoch + 1).Bytes(), - } - - d.session.agent = basepeerleecher.New(&d.Wg, d.cfg.Session, basepeerleecher.EpochDownloaderCallbacks{ - IsProcessed: func(id interface{}) bool { - return d.callback.IsProcessed(id.(hash.Event)) - }, - RequestChunks: func(maxNum uint32, maxSize uint64, chunks uint32) error { - return d.callback.RequestChunk(peer, - dagstream.Request{ - Session: session, - Limit: dag.Metric{Num: idx.Event(maxNum), Size: maxSize}, - Type: typ, - MaxChunks: chunks, - }) - }, - Suspend: func() bool { - return d.callback.Suspend(peer) - }, - Done: func() bool { - return false - }, - }) - - now := time.Now() - d.session.startTime = now - d.session.lastReceived = now - d.session.endTime = now - d.session.try++ - d.session.peer = peer - - d.session.agent.Start() - - d.forceSyncing = false -} - -func (d *Leecher) OnNewEpoch(myEpoch idx.Epoch) { - d.Mu.Lock() - defer d.Mu.Unlock() - - if d.Terminated { - return - } - - d.terminateSession() - - d.epoch = myEpoch - d.session.try = 0 - d.emptyState = true - - d.Routine() -} - -func (d *Leecher) ForceSyncing() { - d.Mu.Lock() - defer d.Mu.Unlock() - d.forceSyncing = true -} - -func (d *Leecher) NotifyChunkReceived(sessionID uint32, last hash.Event, done bool) error { - d.Mu.Lock() - defer d.Mu.Unlock() - if d.session.agent == nil { - return nil - } - if getSessionID(d.epoch, d.session.try-1) != sessionID { - return nil - } - - d.session.lastReceived = time.Now() - if done { - d.terminateSession() - return nil - } - return d.session.agent.NotifyChunkReceived(last) -} diff --git a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/leecher_test.go b/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/leecher_test.go deleted file mode 100644 index 60bce69..0000000 --- a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamleecher/leecher_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package dagstreamleecher - -import ( - "math/rand" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/dag/dagstream" -) - -func TestLeecherNoDeadlocks(t *testing.T) { - for try := 0; try < 10; try++ { - testLeecherNoDeadlocks(t, 1+rand.Intn(500)) - } -} - -type peerRequest struct { - peer string - request dagstream.Request -} - -func testLeecherNoDeadlocks(t *testing.T, maxPeers int) { - requests := make(chan peerRequest, 1000) - config := LiteConfig() - config.RecheckInterval = time.Millisecond * 5 - config.MinSessionRestart = 2 * time.Millisecond * 5 - config.MaxSessionRestart = 5 * time.Millisecond * 5 - config.BaseProgressWatchdog = 3 * time.Millisecond * 5 - config.Session.RecheckInterval = time.Millisecond - epoch := idx.Epoch(1) - leecher := New(epoch, rand.Intn(2) == 0, config, Callbacks{ - IsProcessed: func(id hash.Event) bool { - return rand.Intn(2) == 0 - }, - RequestChunk: func(peer string, r dagstream.Request) error { - requests <- peerRequest{peer, r} - return nil - }, - Suspend: func(peer string) bool { - return rand.Intn(10) == 0 - }, - PeerEpoch: func(peer string) idx.Epoch { - return 1 + epoch/2 + idx.Epoch(rand.Intn(int(epoch*2))) - }, - }) - terminated := false - for i := 0; i < maxPeers*2; i++ { - peer := strconv.Itoa(rand.Intn(maxPeers)) - coin := rand.Intn(100) - if coin <= 50 { - err := leecher.RegisterPeer(peer) - if !terminated { - require.NoError(t, err) - } - } else if coin <= 60 { - err := leecher.UnregisterPeer(peer) - if !terminated { - require.NoError(t, err) - } - } else if coin <= 65 { - epoch++ - leecher.OnNewEpoch(epoch) - } else if coin <= 70 { - leecher.ForceSyncing() - } else { - time.Sleep(time.Millisecond) - } - select { - case req := <-requests: - if rand.Intn(10) != 0 { - err := leecher.NotifyChunkReceived(req.request.Session.ID, hash.FakeEvent(), rand.Intn(5) == 0) - if !terminated { - require.NoError(t, err) - } - } - default: - } - if !terminated && rand.Intn(maxPeers*2) == 0 { - terminated = true - leecher.Terminate() - } - } - if !terminated { - leecher.Stop() - } else { - leecher.Wg.Wait() - } -} diff --git a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamseeder/config.go b/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamseeder/config.go deleted file mode 100644 index 6ede1eb..0000000 --- a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamseeder/config.go +++ /dev/null @@ -1,19 +0,0 @@ -package dagstreamseeder - -import ( - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamseeder" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" -) - -type Config basestreamseeder.Config - -func DefaultConfig(scale cachescale.Func) Config { - return Config{ - SenderThreads: 8, - MaxSenderTasks: 128, - MaxPendingResponsesSize: scale.I64(64 * 1024 * 1024), - MaxResponsePayloadNum: 16384, - MaxResponsePayloadSize: 8 * 1024 * 1024, - MaxResponseChunks: 12, - } -} diff --git a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamseeder/seeder.go b/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamseeder/seeder.go deleted file mode 100644 index 03a52a8..0000000 --- a/evm/go-x1/gossip/protocols/dag/dagstream/dagstreamseeder/seeder.go +++ /dev/null @@ -1,95 +0,0 @@ -package dagstreamseeder - -import ( - "errors" - - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream" - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamseeder" - "github.com/Fantom-foundation/lachesis-base/hash" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/dag/dagstream" -) - -var ( - ErrWrongType = errors.New("wrong request type") - ErrWrongSelectorLen = errors.New("wrong event selector length") -) - -type Seeder struct { - *basestreamseeder.BaseSeeder -} - -type Callbacks struct { - ForEachEvent func(start []byte, onEvent func(key hash.Event, eventB rlp.RawValue) bool) -} - -type Peer struct { - ID string - SendChunk func(dagstream.Response, hash.Events) error - Misbehaviour func(error) -} - -func New(cfg Config, callbacks Callbacks) *Seeder { - return &Seeder{ - BaseSeeder: basestreamseeder.New(basestreamseeder.Config(cfg), basestreamseeder.Callbacks{ - ForEachItem: func(start basestream.Locator, rType basestream.RequestType, onKey func(basestream.Locator) bool, onAppended func(basestream.Payload) bool) basestream.Payload { - res := &dagstream.Payload{ - IDs: hash.Events{}, - Events: []rlp.RawValue{}, - Size: 0, - } - callbacks.ForEachEvent(start.(dagstream.Locator), func(key hash.Event, eventB rlp.RawValue) bool { - if !onKey(dagstream.Locator(key.Bytes())) { - return false - } - if rType == dagstream.RequestIDs { - res.AddID(key, len(eventB)) - } else { - res.AddEvent(key, eventB) - } - return onAppended(res) - }) - return res - }, - }), - } -} - -func (s *Seeder) NotifyRequestReceived(peer Peer, r dagstream.Request) (err error, peerErr error) { - if len(r.Session.Start) > len(hash.ZeroEvent) || len(r.Session.Stop) > len(hash.ZeroEvent) { - return nil, ErrWrongSelectorLen - } - if r.Type != dagstream.RequestIDs && r.Type != dagstream.RequestEvents { - return nil, ErrWrongType - } - rType := r.Type - return s.BaseSeeder.NotifyRequestReceived(basestreamseeder.Peer{ - ID: peer.ID, - SendChunk: func(response basestream.Response) error { - payload := response.Payload.(*dagstream.Payload) - payloadIDs := payload.IDs - if rType == dagstream.RequestEvents { - payloadIDs = payloadIDs[:0] - } - return peer.SendChunk(dagstream.Response{ - SessionID: response.SessionID, - Done: response.Done, - IDs: payloadIDs, - Events: payload.Events, - }, payload.IDs) - }, - Misbehaviour: peer.Misbehaviour, - }, basestream.Request{ - Session: basestream.Session{ - ID: r.Session.ID, - Start: r.Session.Start, - Stop: r.Session.Stop, - }, - Type: r.Type, - MaxPayloadNum: uint32(r.Limit.Num), - MaxPayloadSize: r.Limit.Size, - MaxChunks: r.MaxChunks, - }) -} diff --git a/evm/go-x1/gossip/protocols/dag/dagstream/types.go b/evm/go-x1/gossip/protocols/dag/dagstream/types.go deleted file mode 100644 index 72941c1..0000000 --- a/evm/go-x1/gossip/protocols/dag/dagstream/types.go +++ /dev/null @@ -1,82 +0,0 @@ -package dagstream - -import ( - "bytes" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" -) - -type Request struct { - Session Session - Limit dag.Metric - Type basestream.RequestType - MaxChunks uint32 -} - -type Response struct { - SessionID uint32 - Done bool - IDs hash.Events - Events []rlp.RawValue -} - -type Session struct { - ID uint32 - Start Locator - Stop Locator -} - -type Locator []byte - -func (l Locator) Compare(b basestream.Locator) int { - return bytes.Compare(l, b.(Locator)) -} - -func (l Locator) Inc() basestream.Locator { - nextBn := new(big.Int).SetBytes(l) - nextBn.Add(nextBn, common.Big1) - return Locator(common.LeftPadBytes(nextBn.Bytes(), len(l))) -} - -type Payload struct { - IDs hash.Events - Events []rlp.RawValue - Size uint64 -} - -func (p *Payload) AddEvent(id hash.Event, eventB rlp.RawValue) { - p.IDs = append(p.IDs, id) - p.Events = append(p.Events, eventB) - p.Size += uint64(len(eventB)) -} - -func (p *Payload) AddID(id hash.Event, size int) { - p.IDs = append(p.IDs, id) - p.Size += uint64(size) -} - -func (p Payload) Len() int { - return len(p.IDs) -} - -func (p Payload) TotalSize() uint64 { - return p.Size -} - -func (p Payload) TotalMemSize() int { - if len(p.Events) != 0 { - return int(p.Size) + len(p.IDs)*128 - } - return len(p.IDs) * 128 -} - -const ( - RequestIDs basestream.RequestType = 0 - RequestEvents basestream.RequestType = 2 -) diff --git a/evm/go-x1/gossip/protocols/epochpacks/epprocessor/config.go b/evm/go-x1/gossip/protocols/epochpacks/epprocessor/config.go deleted file mode 100644 index 82fc9e6..0000000 --- a/evm/go-x1/gossip/protocols/epochpacks/epprocessor/config.go +++ /dev/null @@ -1,29 +0,0 @@ -package epprocessor - -import ( - "time" - - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" -) - -type Config struct { - BufferLimit dag.Metric - - SemaphoreTimeout time.Duration - - MaxTasks int -} - -func DefaultConfig(scale cachescale.Func) Config { - return Config{ - BufferLimit: dag.Metric{ - Num: 10000, - Size: scale.U64(15 * opt.MiB), - }, - SemaphoreTimeout: 10 * time.Second, - MaxTasks: 512, - } -} diff --git a/evm/go-x1/gossip/protocols/epochpacks/epprocessor/processor.go b/evm/go-x1/gossip/protocols/epochpacks/epprocessor/processor.go deleted file mode 100644 index bf99d8c..0000000 --- a/evm/go-x1/gossip/protocols/epochpacks/epprocessor/processor.go +++ /dev/null @@ -1,167 +0,0 @@ -package epprocessor - -import ( - "errors" - "sync" - - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/datasemaphore" - "github.com/Fantom-foundation/lachesis-base/utils/workers" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iep" - "github.com/Fantom-foundation/go-opera/inter/ier" -) - -var ( - ErrBusy = errors.New("failed to acquire events semaphore") -) - -// Processor is responsible for processing incoming events -type Processor struct { - cfg Config - - quit chan struct{} - wg sync.WaitGroup - - callback Callback - - inserter *workers.Workers - checker *workers.Workers - - itemsSemaphore *datasemaphore.DataSemaphore -} - -type ItemCallback struct { - ProcessEV func(ev inter.LlrSignedEpochVote) error - ProcessER func(er ier.LlrIdxFullEpochRecord) error - ReleasedEV func(ev inter.LlrSignedEpochVote, peer string, err error) - ReleasedER func(er ier.LlrIdxFullEpochRecord, peer string, err error) - CheckEV func(ev inter.LlrSignedEpochVote, checked func(error)) -} - -type Callback struct { - Item ItemCallback -} - -// New creates an event processor -func New(itemsSemaphore *datasemaphore.DataSemaphore, cfg Config, callback Callback) *Processor { - f := &Processor{ - cfg: cfg, - quit: make(chan struct{}), - itemsSemaphore: itemsSemaphore, - callback: callback, - } - f.callback = callback - f.inserter = workers.New(&f.wg, f.quit, cfg.MaxTasks) - f.checker = workers.New(&f.wg, f.quit, cfg.MaxTasks) - return f -} - -// Start boots up the items processor. -func (f *Processor) Start() { - f.inserter.Start(1) - f.checker.Start(1) -} - -// Stop interrupts the processor, canceling all the pending operations. -// Stop waits until all the internal goroutines have finished. -func (f *Processor) Stop() { - close(f.quit) - f.itemsSemaphore.Terminate() - f.wg.Wait() -} - -// Overloaded returns true if too much items are being processed -func (f *Processor) Overloaded() bool { - return f.TasksCount() > f.cfg.MaxTasks*3/4 -} - -type checkRes struct { - ev inter.LlrSignedEpochVote - err error - pos idx.Event -} - -func (f *Processor) Enqueue(peer string, eps []iep.LlrEpochPack, totalSize uint64, done func()) error { - if len(eps) == 0 { - if done != nil { - done() - } - return nil - } - metric := dag.Metric{Num: idx.Event(len(eps)), Size: totalSize} - if !f.itemsSemaphore.Acquire(metric, f.cfg.SemaphoreTimeout) { - return ErrBusy - } - - // process each EpochPack as a separate task - return f.inserter.Enqueue(func() { - if done != nil { - defer done() - } - defer f.itemsSemaphore.Release(metric) - for _, ep := range eps { - items := ep.Votes - record := ep.Record - checkedC := make(chan *checkRes, len(items)) - err := f.checker.Enqueue(func() { - for i, v := range items { - pos := idx.Event(i) - ev := v - f.callback.Item.CheckEV(ev, func(err error) { - checkedC <- &checkRes{ - ev: ev, - err: err, - pos: pos, - } - }) - } - }) - if err != nil { - return - } - itemsLen := len(items) - var orderedResults = make([]*checkRes, itemsLen) - var processed int - for processed < itemsLen { - select { - case res := <-checkedC: - orderedResults[res.pos] = res - - for i := processed; processed < len(orderedResults) && orderedResults[i] != nil; i++ { - f.processEV(peer, orderedResults[i].ev, orderedResults[i].err) - orderedResults[i] = nil // free the memory - processed++ - } - - case <-f.quit: - return - } - } - f.processER(peer, record) - } - }) -} - -func (f *Processor) processEV(peer string, ev inter.LlrSignedEpochVote, resErr error) { - // release item if failed validation - if resErr != nil { - f.callback.Item.ReleasedEV(ev, peer, resErr) - return - } - // process item - err := f.callback.Item.ProcessEV(ev) - f.callback.Item.ReleasedEV(ev, peer, err) -} - -func (f *Processor) processER(peer string, er ier.LlrIdxFullEpochRecord) { - // process item - err := f.callback.Item.ProcessER(er) - f.callback.Item.ReleasedER(er, peer, err) -} - -func (f *Processor) TasksCount() int { - return f.inserter.TasksCount() + f.checker.TasksCount() -} diff --git a/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamleecher/config.go b/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamleecher/config.go deleted file mode 100644 index 7e8d9b3..0000000 --- a/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamleecher/config.go +++ /dev/null @@ -1,42 +0,0 @@ -package epstreamleecher - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher/basepeerleecher" -) - -type Config struct { - Session basepeerleecher.EpochDownloaderConfig - RecheckInterval time.Duration - BaseProgressWatchdog time.Duration - BaseSessionWatchdog time.Duration - MinSessionRestart time.Duration - MaxSessionRestart time.Duration -} - -// DefaultConfig returns default leecher config -func DefaultConfig() Config { - return Config{ - Session: basepeerleecher.EpochDownloaderConfig{ - DefaultChunkItemsNum: 500, - DefaultChunkItemsSize: 512 * 1024, - ParallelChunksDownload: 6, - RecheckInterval: 10 * time.Millisecond, - }, - RecheckInterval: time.Second, - BaseProgressWatchdog: time.Second * 5, - BaseSessionWatchdog: time.Second * 30 * 5, - MinSessionRestart: time.Second * 5, - MaxSessionRestart: time.Minute * 5, - } -} - -// LiteConfig returns default leecher config for tests -func LiteConfig() Config { - cfg := DefaultConfig() - cfg.Session.DefaultChunkItemsSize /= 10 - cfg.Session.DefaultChunkItemsNum /= 10 - cfg.Session.ParallelChunksDownload = cfg.Session.ParallelChunksDownload/2 + 1 - return cfg -} diff --git a/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamleecher/leecher.go b/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamleecher/leecher.go deleted file mode 100644 index fe84147..0000000 --- a/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamleecher/leecher.go +++ /dev/null @@ -1,201 +0,0 @@ -package epstreamleecher - -import ( - "math/rand" - "time" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher" - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamleecher/basepeerleecher" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epstream" -) - -// Leecher is responsible for requesting EPs based on lexicographic EPs streams -type Leecher struct { - *basestreamleecher.BaseLeecher - - // Callbacks - callback Callbacks - - cfg Config - - // State - session sessionState - - forceSyncing bool -} - -// New creates an EPs downloader to request EPs based on lexicographic EPs streams -func New(cfg Config, callback Callbacks) *Leecher { - l := &Leecher{ - cfg: cfg, - callback: callback, - } - l.BaseLeecher = basestreamleecher.New(cfg.RecheckInterval, basestreamleecher.Callbacks{ - SelectSessionPeerCandidates: l.selectSessionPeerCandidates, - ShouldTerminateSession: l.shouldTerminateSession, - StartSession: l.startSession, - TerminateSession: l.terminateSession, - OngoingSession: func() bool { - return l.session.agent != nil - }, - OngoingSessionPeer: func() string { - return l.session.peer - }, - }) - return l -} - -type Callbacks struct { - LowestEpochToFetch func() idx.Epoch - MaxEpochToFetch func() idx.Epoch - IsProcessed func(idx.Epoch) bool - - RequestChunk func(peer string, r epstream.Request) error - Suspend func(peer string) bool - PeerEpoch func(peer string) idx.Epoch -} - -type sessionState struct { - agent *basepeerleecher.BasePeerLeecher - peer string - startTime time.Time - endTime time.Time - lastReceived time.Time - try uint32 - - sessionID uint32 - - lowestEpochToFetch idx.Epoch -} - -func (d *Leecher) shouldTerminateSession() bool { - if d.session.agent.Stopped() { - return true - } - - noProgress := time.Since(d.session.lastReceived) >= d.cfg.BaseProgressWatchdog*time.Duration(d.session.try+5)/5 - stuck := time.Since(d.session.startTime) >= d.cfg.BaseSessionWatchdog*time.Duration(d.session.try+5)/5 - return stuck || noProgress -} - -func (d *Leecher) terminateSession() { - // force the epoch download to end - if d.session.agent != nil { - d.session.agent.Terminate() - d.session.agent = nil - d.session.endTime = time.Now() - if d.callback.LowestEpochToFetch() >= d.session.lowestEpochToFetch+idx.Epoch(d.cfg.Session.DefaultChunkItemsNum) { - // reset the counter of unsuccessful sync attempts - d.session.try = 0 - } - } -} - -func (d *Leecher) selectSessionPeerCandidates() []string { - knowledgeablePeers := make([]string, 0, len(d.Peers)) - allPeers := make([]string, 0, len(d.Peers)) - start := d.callback.LowestEpochToFetch() - if start >= d.callback.MaxEpochToFetch() { - return nil - } - for p := range d.Peers { - epoch := d.callback.PeerEpoch(p) - if epoch >= start { - knowledgeablePeers = append(knowledgeablePeers, p) - } - allPeers = append(allPeers, p) - } - sinceEnd := time.Since(d.session.endTime) - waitUntilProcessed := d.session.try == 0 || sinceEnd > d.cfg.MinSessionRestart - hasSomethingToSync := d.session.try == 0 || len(knowledgeablePeers) > 0 || sinceEnd >= d.cfg.MaxSessionRestart || d.forceSyncing - if waitUntilProcessed && hasSomethingToSync { - if len(knowledgeablePeers) > 0 && d.session.try%5 != 4 { - // normally work only with peers which have a higher epoch - return knowledgeablePeers - } else { - // if above doesn't work, try other peers on 5th try - return allPeers - } - } - return nil -} - -func getSessionID(epoch idx.Epoch, try uint32) uint32 { - return (uint32(epoch) << 12) ^ try -} - -func (d *Leecher) startSession(candidates []string) { - peer := candidates[rand.Intn(len(candidates))] - - start := d.callback.LowestEpochToFetch() - end := d.callback.MaxEpochToFetch() - if end <= start { - end = start + 1 - } - session := epstream.Session{ - ID: getSessionID(start, d.session.try), - Start: epstream.Locator(start), - Stop: epstream.Locator(end), - } - - d.session.agent = basepeerleecher.New(&d.Wg, d.cfg.Session, basepeerleecher.EpochDownloaderCallbacks{ - IsProcessed: func(id interface{}) bool { - lastEpoch := id.(idx.Epoch) - return d.callback.IsProcessed(lastEpoch) - }, - RequestChunks: func(maxNum uint32, maxSize uint64, chunks uint32) error { - return d.callback.RequestChunk(peer, - epstream.Request{ - Session: session, - Limit: epstream.Metric{Num: idx.Epoch(maxNum), Size: maxSize}, - Type: 0, - MaxChunks: chunks, - }) - }, - Suspend: func() bool { - return d.callback.Suspend(peer) - }, - Done: func() bool { - return false - }, - }) - - now := time.Now() - d.session.startTime = now - d.session.lastReceived = now - d.session.endTime = now - d.session.try++ - d.session.peer = peer - d.session.sessionID = session.ID - d.session.lowestEpochToFetch = start - - d.session.agent.Start() - - d.forceSyncing = false -} - -func (d *Leecher) ForceSyncing() { - d.Mu.Lock() - defer d.Mu.Unlock() - d.forceSyncing = true -} - -func (d *Leecher) NotifyChunkReceived(sessionID uint32, lastEpoch idx.Epoch, done bool) error { - d.Mu.Lock() - defer d.Mu.Unlock() - if d.session.agent == nil { - return nil - } - if d.session.sessionID != sessionID { - return nil - } - - d.session.lastReceived = time.Now() - if done { - d.terminateSession() - return nil - } - return d.session.agent.NotifyChunkReceived(lastEpoch) -} diff --git a/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamseeder/config.go b/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamseeder/config.go deleted file mode 100644 index 81c7ae5..0000000 --- a/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamseeder/config.go +++ /dev/null @@ -1,19 +0,0 @@ -package epstreamseeder - -import ( - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamseeder" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" -) - -type Config basestreamseeder.Config - -func DefaultConfig(scale cachescale.Func) Config { - return Config{ - SenderThreads: 2, - MaxSenderTasks: 64, - MaxPendingResponsesSize: scale.I64(32 * 1024 * 1024), - MaxResponsePayloadNum: 4096, - MaxResponsePayloadSize: 8 * 1024 * 1024, - MaxResponseChunks: 12, - } -} diff --git a/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamseeder/seeder.go b/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamseeder/seeder.go deleted file mode 100644 index 0b12d47..0000000 --- a/evm/go-x1/gossip/protocols/epochpacks/epstream/epstreamseeder/seeder.go +++ /dev/null @@ -1,82 +0,0 @@ -package epstreamseeder - -import ( - "errors" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream" - "github.com/Fantom-foundation/lachesis-base/gossip/basestream/basestreamseeder" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/epochpacks/epstream" -) - -var ( - ErrWrongType = errors.New("wrong request type") -) - -type Seeder struct { - *basestreamseeder.BaseSeeder -} - -type Callbacks struct { - Iterate func(start idx.Epoch, f func(epoch idx.Epoch, eps rlp.RawValue) bool) -} - -type Peer struct { - ID string - SendChunk func(epstream.Response) error - Misbehaviour func(error) -} - -func New(cfg Config, callbacks Callbacks) *Seeder { - return &Seeder{ - BaseSeeder: basestreamseeder.New(basestreamseeder.Config(cfg), basestreamseeder.Callbacks{ - ForEachItem: func(start basestream.Locator, _ basestream.RequestType, onKey func(key basestream.Locator) bool, onAppended func(items basestream.Payload) bool) basestream.Payload { - res := &epstream.Payload{ - Items: []rlp.RawValue{}, - Keys: []epstream.Locator{}, - Size: 0, - } - st := start.(epstream.Locator) - callbacks.Iterate(idx.Epoch(st), func(epoch idx.Epoch, eps rlp.RawValue) bool { - key := epstream.Locator(epoch) - if !onKey(key) { - return false - } - res.AddEpochPacks(key, eps) - return onAppended(res) - }) - return res - }, - }), - } -} - -func (s *Seeder) NotifyRequestReceived(peer Peer, r epstream.Request) (err error, peerErr error) { - if r.Type != 0 { - return nil, ErrWrongType - } - return s.BaseSeeder.NotifyRequestReceived(basestreamseeder.Peer{ - ID: peer.ID, - SendChunk: func(response basestream.Response) error { - return peer.SendChunk(epstream.Response{ - SessionID: response.SessionID, - Done: response.Done, - Payload: response.Payload.(*epstream.Payload).Items, - }) - }, - Misbehaviour: peer.Misbehaviour, - }, basestream.Request{ - Session: basestream.Session{ - ID: r.Session.ID, - Start: r.Session.Start, - Stop: r.Session.Stop, - }, - Type: r.Type, - MaxPayloadNum: uint32(r.Limit.Num), - MaxPayloadSize: r.Limit.Size, - MaxChunks: r.MaxChunks, - }) -} diff --git a/evm/go-x1/gossip/protocols/epochpacks/epstream/types.go b/evm/go-x1/gossip/protocols/epochpacks/epstream/types.go deleted file mode 100644 index bbb71fd..0000000 --- a/evm/go-x1/gossip/protocols/epochpacks/epstream/types.go +++ /dev/null @@ -1,78 +0,0 @@ -package epstream - -import ( - "fmt" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/lachesis-base/gossip/basestream" -) - -type Request struct { - Session Session - Limit Metric - Type basestream.RequestType - MaxChunks uint32 -} - -type Response struct { - SessionID uint32 - Done bool - Payload []rlp.RawValue -} - -type Session struct { - ID uint32 - Start Locator - Stop Locator -} - -type Locator idx.Epoch - -func (l Locator) Compare(b basestream.Locator) int { - if l == b.(Locator) { - return 0 - } - if l < b.(Locator) { - return -1 - } - return 1 -} - -func (l Locator) Inc() basestream.Locator { - return l + 1 -} - -type Payload struct { - Items []rlp.RawValue - Keys []Locator - Size uint64 -} - -func (p *Payload) AddEpochPacks(id Locator, epsB rlp.RawValue) { - p.Items = append(p.Items, epsB) - p.Keys = append(p.Keys, id) - p.Size += uint64(len(epsB)) -} - -func (p Payload) Len() int { - return len(p.Keys) -} - -func (p Payload) TotalSize() uint64 { - return p.Size -} - -func (p Payload) TotalMemSize() int { - return int(p.Size) + len(p.Keys)*32 -} - -type Metric struct { - Num idx.Epoch - Size uint64 -} - -func (m Metric) String() string { - return fmt.Sprintf("{Num=%d,Size=%d}", m.Num, m.Size) -} diff --git a/evm/go-x1/gossip/protocols/snap/api.go b/evm/go-x1/gossip/protocols/snap/api.go deleted file mode 100644 index 8e762f6..0000000 --- a/evm/go-x1/gossip/protocols/snap/api.go +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package snap - -import ( - "context" - "sync" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/rpc" - - "github.com/Fantom-foundation/go-opera/gossip/protocols/snap/snapstream/snapleecher" -) - -// PublicDownloaderAPI provides an API which gives information about the current synchronisation status. -// It offers only methods that operates on data that can be available to anyone without security risks. -type PublicDownloaderAPI struct { - l *snapleecher.Leecher - mux *event.TypeMux - installSyncSubscription chan chan interface{} - uninstallSyncSubscription chan *uninstallSyncSubscriptionRequest -} - -// NewPublicDownloaderAPI create a new PublicDownloaderAPI. The API has an internal event loop that -// listens for events from the downloader through the global event mux. In case it receives one of -// these events it broadcasts it to all syncing subscriptions that are installed through the -// installSyncSubscription channel. -func NewPublicDownloaderAPI(l *snapleecher.Leecher, m *event.TypeMux) *PublicDownloaderAPI { - api := &PublicDownloaderAPI{ - l: l, - mux: m, - installSyncSubscription: make(chan chan interface{}), - uninstallSyncSubscription: make(chan *uninstallSyncSubscriptionRequest), - } - - go api.eventLoop() - - return api -} - -// eventLoop runs a loop until the event mux closes. It will install and uninstall new -// sync subscriptions and broadcasts sync status updates to the installed sync subscriptions. -func (api *PublicDownloaderAPI) eventLoop() { - var ( - sub = api.mux.Subscribe(StartEvent{}, DoneEvent{}, FailedEvent{}) - syncSubscriptions = make(map[chan interface{}]struct{}) - ) - - for { - select { - case i := <-api.installSyncSubscription: - syncSubscriptions[i] = struct{}{} - case u := <-api.uninstallSyncSubscription: - delete(syncSubscriptions, u.c) - close(u.uninstalled) - case event := <-sub.Chan(): - if event == nil { - return - } - - var notification interface{} - switch event.Data.(type) { - case StartEvent: - notification = &SyncingResult{ - Syncing: true, - Status: api.l.Progress(), - } - case DoneEvent, FailedEvent: - notification = false - } - // broadcast - for c := range syncSubscriptions { - c <- notification - } - } - } -} - -// Syncing provides information when this nodes starts synchronising with the Ethereum network and when it's finished. -func (api *PublicDownloaderAPI) Syncing(ctx context.Context) (*rpc.Subscription, error) { - notifier, supported := rpc.NotifierFromContext(ctx) - if !supported { - return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported - } - - rpcSub := notifier.CreateSubscription() - - go func() { - statuses := make(chan interface{}) - sub := api.SubscribeSyncStatus(statuses) - - for { - select { - case status := <-statuses: - notifier.Notify(rpcSub.ID, status) - case <-rpcSub.Err(): - sub.Unsubscribe() - return - case <-notifier.Closed(): - sub.Unsubscribe() - return - } - } - }() - - return rpcSub, nil -} - -// SyncingResult provides information about the current synchronisation status for this node. -type SyncingResult struct { - Syncing bool `json:"syncing"` - Status ethereum.SyncProgress `json:"status"` -} - -// uninstallSyncSubscriptionRequest uninstalles a syncing subscription in the API event loop. -type uninstallSyncSubscriptionRequest struct { - c chan interface{} - uninstalled chan interface{} -} - -// SyncStatusSubscription represents a syncing subscription. -type SyncStatusSubscription struct { - api *PublicDownloaderAPI // register subscription in event loop of this api instance - c chan interface{} // channel where events are broadcasted to - unsubOnce sync.Once // make sure unsubscribe logic is executed once -} - -// Unsubscribe uninstalls the subscription from the DownloadAPI event loop. -// The status channel that was passed to subscribeSyncStatus isn't used anymore -// after this method returns. -func (s *SyncStatusSubscription) Unsubscribe() { - s.unsubOnce.Do(func() { - req := uninstallSyncSubscriptionRequest{s.c, make(chan interface{})} - s.api.uninstallSyncSubscription <- &req - - for { - select { - case <-s.c: - // drop new status events until uninstall confirmation - continue - case <-req.uninstalled: - return - } - } - }) -} - -// SubscribeSyncStatus creates a subscription that will broadcast new synchronisation updates. -// The given channel must receive interface values, the result can either -func (api *PublicDownloaderAPI) SubscribeSyncStatus(status chan interface{}) *SyncStatusSubscription { - api.installSyncSubscription <- status - return &SyncStatusSubscription{api: api, c: status} -} diff --git a/evm/go-x1/gossip/protocols/snap/events.go b/evm/go-x1/gossip/protocols/snap/events.go deleted file mode 100644 index 1e0eba1..0000000 --- a/evm/go-x1/gossip/protocols/snap/events.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package snap - -import "github.com/ethereum/go-ethereum/core/types" - -type DoneEvent struct { - Latest *types.Header -} -type StartEvent struct{} -type FailedEvent struct{ Err error } diff --git a/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/leecher.go b/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/leecher.go deleted file mode 100644 index bde7209..0000000 --- a/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/leecher.go +++ /dev/null @@ -1,131 +0,0 @@ -package snapleecher - -import ( - "errors" - "fmt" - "sync" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/eth/protocols/snap" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/trie" -) - -var ( - MaxStateFetch = 384 // Amount of node state values to allow fetching per request -) - -var ( - errTimeout = errors.New("timeout") - errCancelStateFetch = errors.New("state data download canceled (requested)") - errCanceled = errors.New("syncing canceled (requested)") -) - -type Leecher struct { - peers *peerSet // Set of active peers from which download can proceed - // Callbacks - dropPeer peerDropFn // Drops a peer for misbehaving - - stateDB ethdb.Database // Database to state sync into (and deduplicate via) - stateBloom *trie.SyncBloom // Bloom filter for fast trie node and contract code existence checks - SnapSyncer *snap.Syncer // TODO(karalabe): make private! hack for now - - stateSyncStart chan *stateSync - trackStateReq chan *stateReq - stateCh chan dataPack // Channel receiving inbound node state data - - // Statistics - syncStatsState stateSyncStats - syncStatsLock sync.RWMutex // Lock protecting the sync stats fields - - // Cancellation and termination - cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop) - cancelCh chan struct{} // Channel to cancel mid-flight syncs - cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers - cancelWg sync.WaitGroup // Make sure all fetcher goroutines have exited. - - quitCh chan struct{} // Quit channel to signal termination -} - -// New creates a new downloader to fetch hashes and blocks from remote peers. -func New(stateDb ethdb.Database, stateBloom *trie.SyncBloom, dropPeer peerDropFn) *Leecher { - d := &Leecher{ - stateDB: stateDb, - stateBloom: stateBloom, - dropPeer: dropPeer, - peers: newPeerSet(), - quitCh: make(chan struct{}), - stateCh: make(chan dataPack), - SnapSyncer: snap.NewSyncer(stateDb), - stateSyncStart: make(chan *stateSync), - syncStatsState: stateSyncStats{ - processed: rawdb.ReadFastTrieProgress(stateDb), - }, - trackStateReq: make(chan *stateReq), - } - go d.stateFetcher() - return d -} - -// cancel aborts all of the operations and resets the queue. However, cancel does -// not wait for the running download goroutines to finish. This method should be -// used when cancelling the downloads from inside the downloader. -func (d *Leecher) cancel() { - // Close the current cancel channel - d.cancelLock.Lock() - defer d.cancelLock.Unlock() - - if d.cancelCh != nil { - select { - case <-d.cancelCh: - // Channel was already closed - default: - close(d.cancelCh) - } - } -} - -// DeliverSnapPacket is invoked from a peer's message handler when it transmits a -// data packet for the local node to consume. -func (d *Leecher) DeliverSnapPacket(peer *snap.Peer, packet snap.Packet) error { - switch packet := packet.(type) { - case *snap.AccountRangePacket: - hashes, accounts, err := packet.Unpack() - if err != nil { - return err - } - return d.SnapSyncer.OnAccounts(peer, packet.ID, hashes, accounts, packet.Proof) - - case *snap.StorageRangesPacket: - hashset, slotset := packet.Unpack() - return d.SnapSyncer.OnStorage(peer, packet.ID, hashset, slotset, packet.Proof) - - case *snap.ByteCodesPacket: - return d.SnapSyncer.OnByteCodes(peer, packet.ID, packet.Codes) - - case *snap.TrieNodesPacket: - return d.SnapSyncer.OnTrieNodes(peer, packet.ID, packet.Nodes) - - default: - return fmt.Errorf("unexpected snap packet type: %T", packet) - } -} - -// Progress retrieves the synchronisation boundaries, specifically the origin -// block where synchronisation started at (may have failed/suspended); the block -// or header sync is currently at; and the latest known block which the sync targets. -// -// In addition, during the state download phase of fast synchronisation the number -// of processed and the total number of known states are also returned. Otherwise -// these are zero. -func (d *Leecher) Progress() ethereum.SyncProgress { - // Lock the current stats and return the progress - d.syncStatsLock.RLock() - defer d.syncStatsLock.RUnlock() - - return ethereum.SyncProgress{ - PulledStates: d.syncStatsState.processed, - KnownStates: d.syncStatsState.processed + d.syncStatsState.pending, - } -} diff --git a/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/peer.go b/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/peer.go deleted file mode 100644 index cdef24f..0000000 --- a/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/peer.go +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Contains the active peer-set of the downloader, maintaining both failures -// as well as reputation metrics to prioritize the block retrievals. - -package snapleecher - -import ( - "errors" - "sort" - "sync" - "sync/atomic" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/eth/protocols/eth" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p/msgrate" -) - -const ( - maxLackingHashes = 4096 // Maximum number of entries allowed on the list or lacking items -) - -var ( - errAlreadyFetching = errors.New("already fetching blocks from peer") - errAlreadyRegistered = errors.New("peer is already registered") - errNotRegistered = errors.New("peer is not registered") -) - -// peerConnection represents an active peer from which hashes and blocks are retrieved. -type peerConnection struct { - id string // Unique identifier of the peer - - stateIdle int32 // Current node data activity state of the peer (idle = 0, active = 1) - - stateStarted time.Time // Time instance when the last node data fetch was started - - rates *msgrate.Tracker // Tracker to hone in on the number of items retrievable per second - lacking map[common.Hash]struct{} // Set of hashes not to request (didn't have previously) - - peer Peer - - version uint // Eth protocol version number to switch strategies - log log.Logger // Contextual logger to add extra infos to peer logs - lock sync.RWMutex -} - -// Peer encapsulates the methods required to synchronise with a remote full peer. -type Peer interface { - RequestNodeData([]common.Hash) error -} - -// newPeerConnection creates a new downloader peer. -func newPeerConnection(id string, version uint, peer Peer, logger log.Logger) *peerConnection { - return &peerConnection{ - id: id, - lacking: make(map[common.Hash]struct{}), - peer: peer, - version: version, - log: logger, - } -} - -// Reset clears the internal state of a peer entity. -func (p *peerConnection) Reset() { - p.lock.Lock() - defer p.lock.Unlock() - - atomic.StoreInt32(&p.stateIdle, 0) - - p.lacking = make(map[common.Hash]struct{}) -} - -// FetchNodeData sends a node state data retrieval request to the remote peer. -func (p *peerConnection) FetchNodeData(hashes []common.Hash) error { - // Short circuit if the peer is already fetching - if !atomic.CompareAndSwapInt32(&p.stateIdle, 0, 1) { - return errAlreadyFetching - } - p.stateStarted = time.Now() - - go p.peer.RequestNodeData(hashes) - - return nil -} - -// SetNodeDataIdle sets the peer to idle, allowing it to execute new state trie -// data retrieval requests. Its estimated state retrieval throughput is updated -// with that measured just now. -func (p *peerConnection) SetNodeDataIdle(delivered int, deliveryTime time.Time) { - p.rates.Update(eth.NodeDataMsg, deliveryTime.Sub(p.stateStarted), delivered) - atomic.StoreInt32(&p.stateIdle, 0) -} - -// NodeDataCapacity retrieves the peers state download allowance based on its -// previously discovered throughput. -func (p *peerConnection) NodeDataCapacity(targetRTT time.Duration) int { - cap := p.rates.Capacity(eth.NodeDataMsg, targetRTT) - if cap > MaxStateFetch { - cap = MaxStateFetch - } - return cap -} - -// MarkLacking appends a new entity to the set of items (blocks, receipts, states) -// that a peer is known not to have (i.e. have been requested before). If the -// set reaches its maximum allowed capacity, items are randomly dropped off. -func (p *peerConnection) MarkLacking(hash common.Hash) { - p.lock.Lock() - defer p.lock.Unlock() - - for len(p.lacking) >= maxLackingHashes { - for drop := range p.lacking { - delete(p.lacking, drop) - break - } - } - p.lacking[hash] = struct{}{} -} - -// Lacks retrieves whether the hash of a blockchain item is on the peers lacking -// list (i.e. whether we know that the peer does not have it). -func (p *peerConnection) Lacks(hash common.Hash) bool { - p.lock.RLock() - defer p.lock.RUnlock() - - _, ok := p.lacking[hash] - return ok -} - -// peerSet represents the collection of active peer participating in the chain -// download procedure. -type peerSet struct { - peers map[string]*peerConnection - rates *msgrate.Trackers // Set of rate trackers to give the sync a common beat - - newPeerFeed event.Feed - peerDropFeed event.Feed - - lock sync.RWMutex -} - -// newPeerSet creates a new peer set top track the active download sources. -func newPeerSet() *peerSet { - return &peerSet{ - peers: make(map[string]*peerConnection), - rates: msgrate.NewTrackers(log.New("proto", "eth")), - } -} - -// SubscribeNewPeers subscribes to peer arrival events. -func (ps *peerSet) SubscribeNewPeers(ch chan<- *peerConnection) event.Subscription { - return ps.newPeerFeed.Subscribe(ch) -} - -// SubscribePeerDrops subscribes to peer departure events. -func (ps *peerSet) SubscribePeerDrops(ch chan<- *peerConnection) event.Subscription { - return ps.peerDropFeed.Subscribe(ch) -} - -// Reset iterates over the current peer set, and resets each of the known peers -// to prepare for a next batch of block retrieval. -func (ps *peerSet) Reset() { - ps.lock.RLock() - defer ps.lock.RUnlock() - - for _, peer := range ps.peers { - peer.Reset() - } -} - -// Register injects a new peer into the working set, or returns an error if the -// peer is already known. -// -// The method also sets the starting throughput values of the new peer to the -// average of all existing peers, to give it a realistic chance of being used -// for data retrievals. -func (ps *peerSet) Register(p *peerConnection) error { - // Register the new peer with some meaningful defaults - ps.lock.Lock() - if _, ok := ps.peers[p.id]; ok { - ps.lock.Unlock() - return errAlreadyRegistered - } - p.rates = msgrate.NewTracker(ps.rates.MeanCapacities(), ps.rates.MedianRoundTrip()) - if err := ps.rates.Track(p.id, p.rates); err != nil { - return err - } - ps.peers[p.id] = p - ps.lock.Unlock() - - ps.newPeerFeed.Send(p) - return nil -} - -// Unregister removes a remote peer from the active set, disabling any further -// actions to/from that particular entity. -func (ps *peerSet) Unregister(id string) error { - ps.lock.Lock() - p, ok := ps.peers[id] - if !ok { - ps.lock.Unlock() - return errNotRegistered - } - delete(ps.peers, id) - ps.rates.Untrack(id) - ps.lock.Unlock() - - ps.peerDropFeed.Send(p) - return nil -} - -// Peer retrieves the registered peer with the given id. -func (ps *peerSet) Peer(id string) *peerConnection { - ps.lock.RLock() - defer ps.lock.RUnlock() - - return ps.peers[id] -} - -// Len returns if the current number of peers in the set. -func (ps *peerSet) Len() int { - ps.lock.RLock() - defer ps.lock.RUnlock() - - return len(ps.peers) -} - -// AllPeers retrieves a flat list of all the peers within the set. -func (ps *peerSet) AllPeers() []*peerConnection { - ps.lock.RLock() - defer ps.lock.RUnlock() - - list := make([]*peerConnection, 0, len(ps.peers)) - for _, p := range ps.peers { - list = append(list, p) - } - return list -} - -// NodeDataIdlePeers retrieves a flat list of all the currently node-data-idle -// peers within the active peer set, ordered by their reputation. -func (ps *peerSet) NodeDataIdlePeers() ([]*peerConnection, int) { - idle := func(p *peerConnection) bool { - return atomic.LoadInt32(&p.stateIdle) == 0 - } - throughput := func(p *peerConnection) int { - return p.rates.Capacity(eth.NodeDataMsg, time.Second) - } - return ps.idlePeers(eth.ETH65, eth.ETH66, idle, throughput) -} - -// idlePeers retrieves a flat list of all currently idle peers satisfying the -// protocol version constraints, using the provided function to check idleness. -// The resulting set of peers are sorted by their capacity. -func (ps *peerSet) idlePeers(minProtocol, maxProtocol uint, idleCheck func(*peerConnection) bool, capacity func(*peerConnection) int) ([]*peerConnection, int) { - ps.lock.RLock() - defer ps.lock.RUnlock() - - var ( - total = 0 - idle = make([]*peerConnection, 0, len(ps.peers)) - tps = make([]int, 0, len(ps.peers)) - ) - for _, p := range ps.peers { - if p.version >= minProtocol && p.version <= maxProtocol { - if idleCheck(p) { - idle = append(idle, p) - tps = append(tps, capacity(p)) - } - total++ - } - } - - // And sort them - sortPeers := &peerCapacitySort{idle, tps} - sort.Sort(sortPeers) - return sortPeers.p, total -} - -// peerCapacitySort implements sort.Interface. -// It sorts peer connections by capacity (descending). -type peerCapacitySort struct { - p []*peerConnection - tp []int -} - -func (ps *peerCapacitySort) Len() int { - return len(ps.p) -} - -func (ps *peerCapacitySort) Less(i, j int) bool { - return ps.tp[i] > ps.tp[j] -} - -func (ps *peerCapacitySort) Swap(i, j int) { - ps.p[i], ps.p[j] = ps.p[j], ps.p[i] - ps.tp[i], ps.tp[j] = ps.tp[j], ps.tp[i] -} diff --git a/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/statesync.go b/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/statesync.go deleted file mode 100644 index 877d0b2..0000000 --- a/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/statesync.go +++ /dev/null @@ -1,330 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package snapleecher - -import ( - "sync" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/trie" - "golang.org/x/crypto/sha3" -) - -// stateReq represents a batch of state fetch requests grouped together into -// a single data retrieval network packet. -type stateReq struct { - nItems uint16 // Number of items requested for download (max is 384, so uint16 is sufficient) - trieTasks map[common.Hash]*trieTask // Trie node download tasks to track previous attempts - codeTasks map[common.Hash]*codeTask // Byte code download tasks to track previous attempts - timeout time.Duration // Maximum round trip time for this to complete - timer *time.Timer // Timer to fire when the RTT timeout expires - peer *peerConnection // Peer that we're requesting from - delivered time.Time // Time when the packet was delivered (independent when we process it) - response [][]byte // Response data of the peer (nil for timeouts) - dropped bool // Flag whether the peer dropped off early -} - -// timedOut returns if this request timed out. -func (req *stateReq) timedOut() bool { - return req.response == nil -} - -// stateSyncStats is a collection of progress stats to report during a state trie -// sync to RPC requests as well as to display in user logs. -type stateSyncStats struct { - processed uint64 // Number of state entries processed - duplicate uint64 // Number of state entries downloaded twice - unexpected uint64 // Number of non-requested state entries received - pending uint64 // Number of still pending state entries -} - -// SyncState starts downloading state with the given root hash. -func (d *Leecher) SyncState(root common.Hash) *stateSync { - // Create the state sync - s := newStateSync(d, root) - select { - case d.stateSyncStart <- s: - // If we tell the statesync to restart with a new root, we also need - // to wait for it to actually also start -- when old requests have timed - // out or been delivered - <-s.started - case <-d.quitCh: - s.err = errCancelStateFetch - close(s.done) - } - return s -} - -// stateFetcher manages the active state sync and accepts requests -// on its behalf. -func (d *Leecher) stateFetcher() { - for { - select { - case s := <-d.stateSyncStart: - for next := s; next != nil; { - next = d.runStateSync(next) - } - case <-d.stateCh: - // Ignore state responses while no sync is running. - case <-d.quitCh: - return - } - } -} - -// runStateSync runs a state synchronisation until it completes or another root -// hash is requested to be switched over to. -func (d *Leecher) runStateSync(s *stateSync) *stateSync { - var ( - active = make(map[string]*stateReq) // Currently in-flight requests - finished []*stateReq // Completed or failed requests - timeout = make(chan *stateReq) // Timed out active requests - ) - log.Trace("State sync starting", "root", s.root) - - defer func() { - // Cancel active request timers on exit. Also set peers to idle so they're - // available for the next sync. - for _, req := range active { - req.timer.Stop() - req.peer.SetNodeDataIdle(int(req.nItems), time.Now()) - } - }() - go s.run() - defer s.Cancel() - - // Listen for peer departure events to cancel assigned tasks - peerDrop := make(chan *peerConnection, 1024) - peerSub := s.d.peers.SubscribePeerDrops(peerDrop) - defer peerSub.Unsubscribe() - - for { - // Enable sending of the first buffered element if there is one. - var ( - deliverReq *stateReq - deliverReqCh chan *stateReq - ) - if len(finished) > 0 { - deliverReq = finished[0] - deliverReqCh = s.deliver - } - - select { - // The stateSync lifecycle: - case next := <-d.stateSyncStart: - d.spindownStateSync(active, finished, timeout, peerDrop) - return next - - case <-s.done: - d.spindownStateSync(active, finished, timeout, peerDrop) - return nil - - // Send the next finished request to the current sync: - case deliverReqCh <- deliverReq: - // Shift out the first request, but also set the emptied slot to nil for GC - copy(finished, finished[1:]) - finished[len(finished)-1] = nil - finished = finished[:len(finished)-1] - - // Handle incoming state packs: - case pack := <-d.stateCh: - // Discard any data not requested (or previously timed out) - req := active[pack.PeerId()] - if req == nil { - log.Debug("Unrequested node data", "peer", pack.PeerId(), "len", pack.Items()) - continue - } - // Finalize the request and queue up for processing - req.timer.Stop() - req.response = pack.(*statePack).states - req.delivered = time.Now() - - finished = append(finished, req) - delete(active, pack.PeerId()) - - // Handle dropped peer connections: - case p := <-peerDrop: - // Skip if no request is currently pending - req := active[p.id] - if req == nil { - continue - } - // Finalize the request and queue up for processing - req.timer.Stop() - req.dropped = true - req.delivered = time.Now() - - finished = append(finished, req) - delete(active, p.id) - - // Handle timed-out requests: - case req := <-timeout: - // If the peer is already requesting something else, ignore the stale timeout. - // This can happen when the timeout and the delivery happens simultaneously, - // causing both pathways to trigger. - if active[req.peer.id] != req { - continue - } - req.delivered = time.Now() - // Move the timed out data back into the download queue - finished = append(finished, req) - delete(active, req.peer.id) - - // Track outgoing state requests: - case req := <-d.trackStateReq: - // If an active request already exists for this peer, we have a problem. In - // theory the trie node schedule must never assign two requests to the same - // peer. In practice however, a peer might receive a request, disconnect and - // immediately reconnect before the previous times out. In this case the first - // request is never honored, alas we must not silently overwrite it, as that - // causes valid requests to go missing and sync to get stuck. - if old := active[req.peer.id]; old != nil { - log.Warn("Busy peer assigned new state fetch", "peer", old.peer.id) - // Move the previous request to the finished set - old.timer.Stop() - old.dropped = true - old.delivered = time.Now() - finished = append(finished, old) - } - // Start a timer to notify the sync loop if the peer stalled. - req.timer = time.AfterFunc(req.timeout, func() { - timeout <- req - }) - active[req.peer.id] = req - } - } -} - -// spindownStateSync 'drains' the outstanding requests; some will be delivered and other -// will time out. This is to ensure that when the next stateSync starts working, all peers -// are marked as idle and de facto _are_ idle. -func (d *Leecher) spindownStateSync(active map[string]*stateReq, finished []*stateReq, timeout chan *stateReq, peerDrop chan *peerConnection) { - log.Trace("State sync spinning down", "active", len(active), "finished", len(finished)) - for len(active) > 0 { - var ( - req *stateReq - reason string - ) - select { - // Handle (drop) incoming state packs: - case pack := <-d.stateCh: - req = active[pack.PeerId()] - reason = "delivered" - // Handle dropped peer connections: - case p := <-peerDrop: - req = active[p.id] - reason = "peerdrop" - // Handle timed-out requests: - case req = <-timeout: - reason = "timeout" - } - if req == nil { - continue - } - req.peer.log.Trace("State peer marked idle (spindown)", "req.items", int(req.nItems), "reason", reason) - req.timer.Stop() - delete(active, req.peer.id) - req.peer.SetNodeDataIdle(int(req.nItems), time.Now()) - } - // The 'finished' set contains deliveries that we were going to pass to processing. - // Those are now moot, but we still need to set those peers as idle, which would - // otherwise have been done after processing - for _, req := range finished { - req.peer.SetNodeDataIdle(int(req.nItems), time.Now()) - } -} - -// stateSync schedules requests for downloading a particular state trie defined -// by a given state root. -type stateSync struct { - d *Leecher // Downloader instance to access and manage current peerset - - root common.Hash // State root currently being synced - sched *trie.Sync // State trie sync scheduler defining the tasks - keccak crypto.KeccakState // Keccak256 hasher to verify deliveries with - - trieTasks map[common.Hash]*trieTask // Set of trie node tasks currently queued for retrieval - codeTasks map[common.Hash]*codeTask // Set of byte code tasks currently queued for retrieval - - numUncommitted int - bytesUncommitted int - - started chan struct{} // Started is signalled once the sync loop starts - - deliver chan *stateReq // Delivery channel multiplexing peer responses - cancel chan struct{} // Channel to signal a termination request - cancelOnce sync.Once // Ensures cancel only ever gets called once - done chan struct{} // Channel to signal termination completion - err error // Any error hit during sync (set before completion) -} - -// trieTask represents a single trie node download task, containing a set of -// peers already attempted retrieval from to detect stalled syncs and abort. -type trieTask struct { - path [][]byte - attempts map[string]struct{} -} - -// codeTask represents a single byte code download task, containing a set of -// peers already attempted retrieval from to detect stalled syncs and abort. -type codeTask struct { - attempts map[string]struct{} -} - -// newStateSync creates a new state trie download scheduler. This method does not -// yet start the sync. The user needs to call run to initiate. -func newStateSync(d *Leecher, root common.Hash) *stateSync { - return &stateSync{ - d: d, - root: root, - sched: state.NewStateSync(root, d.stateDB, d.stateBloom, nil), - keccak: sha3.NewLegacyKeccak256().(crypto.KeccakState), - trieTasks: make(map[common.Hash]*trieTask), - codeTasks: make(map[common.Hash]*codeTask), - deliver: make(chan *stateReq), - cancel: make(chan struct{}), - done: make(chan struct{}), - started: make(chan struct{}), - } -} - -// run starts the task assignment and response processing loop, blocking until -// it finishes, and finally notifying any goroutines waiting for the loop to -// finish. -func (s *stateSync) run() { - close(s.started) - s.err = s.d.SnapSyncer.Sync(s.root, s.cancel) - close(s.done) -} - -// Wait blocks until the sync is done or canceled. -func (s *stateSync) Wait() error { - <-s.done - return s.err -} - -// Cancel cancels the sync and waits until it has shut down. -func (s *stateSync) Cancel() error { - s.cancelOnce.Do(func() { - close(s.cancel) - }) - return s.Wait() -} diff --git a/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/types.go b/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/types.go deleted file mode 100644 index 091f959..0000000 --- a/evm/go-x1/gossip/protocols/snap/snapstream/snapleecher/types.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package snapleecher - -import ( - "fmt" -) - -// peerDropFn is a callback type for dropping a peer detected as malicious. -type peerDropFn func(id string) - -// dataPack is a data message returned by a peer for some query. -type dataPack interface { - PeerId() string - Items() int - Stats() string -} - -// statePack is a batch of states returned by a peer. -type statePack struct { - peerID string - states [][]byte -} - -func (p *statePack) PeerId() string { return p.peerID } -func (p *statePack) Items() int { return len(p.states) } -func (p *statePack) Stats() string { return fmt.Sprintf("%d", len(p.states)) } diff --git a/evm/go-x1/gossip/randselect.go b/evm/go-x1/gossip/randselect.go deleted file mode 100644 index 3982e64..0000000 --- a/evm/go-x1/gossip/randselect.go +++ /dev/null @@ -1,153 +0,0 @@ -package gossip - -import ( - "math/rand" -) - -// wrsItem interface should be implemented by any entries that are to be selected from -// a weightedRandomSelect set. Note that recalculating monotonously decreasing item -// weights on-demand (without constantly calling update) is allowed -type wrsItem interface { - Weight() int64 -} - -// weightedRandomSelect is capable of weighted random selection from a set of items -type weightedRandomSelect struct { - root *wrsNode - idx map[wrsItem]int -} - -// newWeightedRandomSelect returns a new weightedRandomSelect structure -func newWeightedRandomSelect() *weightedRandomSelect { - return &weightedRandomSelect{root: &wrsNode{maxItems: wrsBranches}, idx: make(map[wrsItem]int)} -} - -// update updates an item's weight, adds it if it was non-existent or removes it if -// the new weight is zero. Note that explicitly updating decreasing weights is not necessary. -func (w *weightedRandomSelect) update(item wrsItem) { - w.setWeight(item, item.Weight()) -} - -// remove removes an item from the set -func (w *weightedRandomSelect) remove(item wrsItem) { - w.setWeight(item, 0) -} - -// setWeight sets an item's weight to a specific value (removes it if zero) -func (w *weightedRandomSelect) setWeight(item wrsItem, weight int64) { - idx, ok := w.idx[item] - if ok { - w.root.setWeight(idx, weight) - if weight == 0 { - delete(w.idx, item) - } - } else { - if weight != 0 { - if w.root.itemCnt == w.root.maxItems { - // add a new level - newRoot := &wrsNode{sumWeight: w.root.sumWeight, itemCnt: w.root.itemCnt, level: w.root.level + 1, maxItems: w.root.maxItems * wrsBranches} - newRoot.items[0] = w.root - newRoot.weights[0] = w.root.sumWeight - w.root = newRoot - } - w.idx[item] = w.root.insert(item, weight) - } - } -} - -// choose randomly selects an item from the set, with a chance proportional to its -// current weight. If the weight of the chosen element has been decreased since the -// last stored value, returns it with a newWeight/oldWeight chance, otherwise just -// updates its weight and selects another one -func (w *weightedRandomSelect) choose() wrsItem { - for { - if w.root.sumWeight == 0 { - return nil - } - val := rand.Int63n(w.root.sumWeight) - choice, lastWeight := w.root.choose(val) - weight := choice.Weight() - if weight != lastWeight { - w.setWeight(choice, weight) - } - if weight >= lastWeight || rand.Int63n(lastWeight) < weight { - return choice - } - } -} - -const wrsBranches = 8 // max number of branches in the wrsNode tree - -// wrsNode is a node of a tree structure that can store wrsItems or further wrsNodes. -type wrsNode struct { - items [wrsBranches]interface{} - weights [wrsBranches]int64 - sumWeight int64 - level, itemCnt, maxItems int -} - -// insert recursively inserts a new item to the tree and returns the item index -func (n *wrsNode) insert(item wrsItem, weight int64) int { - branch := 0 - for n.items[branch] != nil && (n.level == 0 || n.items[branch].(*wrsNode).itemCnt == n.items[branch].(*wrsNode).maxItems) { - branch++ - if branch == wrsBranches { - panic(nil) - } - } - n.itemCnt++ - n.sumWeight += weight - n.weights[branch] += weight - if n.level == 0 { - n.items[branch] = item - return branch - } - var subNode *wrsNode - if n.items[branch] == nil { - subNode = &wrsNode{maxItems: n.maxItems / wrsBranches, level: n.level - 1} - n.items[branch] = subNode - } else { - subNode = n.items[branch].(*wrsNode) - } - subIdx := subNode.insert(item, weight) - return subNode.maxItems*branch + subIdx -} - -// setWeight updates the weight of a certain item (which should exist) and returns -// the change of the last weight value stored in the tree -func (n *wrsNode) setWeight(idx int, weight int64) int64 { - if n.level == 0 { - oldWeight := n.weights[idx] - n.weights[idx] = weight - diff := weight - oldWeight - n.sumWeight += diff - if weight == 0 { - n.items[idx] = nil - n.itemCnt-- - } - return diff - } - branchItems := n.maxItems / wrsBranches - branch := idx / branchItems - diff := n.items[branch].(*wrsNode).setWeight(idx-branch*branchItems, weight) - n.weights[branch] += diff - n.sumWeight += diff - if weight == 0 { - n.itemCnt-- - } - return diff -} - -// choose recursively selects an item from the tree and returns it along with its weight -func (n *wrsNode) choose(val int64) (wrsItem, int64) { - for i, w := range n.weights { - if val < w { - if n.level == 0 { - return n.items[i].(wrsItem), n.weights[i] - } - return n.items[i].(*wrsNode).choose(val) - } - val -= w - } - panic(nil) -} diff --git a/evm/go-x1/gossip/service.go b/evm/go-x1/gossip/service.go deleted file mode 100644 index fd19a79..0000000 --- a/evm/go-x1/gossip/service.go +++ /dev/null @@ -1,512 +0,0 @@ -package gossip - -import ( - "errors" - "fmt" - "math/big" - "math/rand" - "sync" - "sync/atomic" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/lachesis" - "github.com/Fantom-foundation/lachesis-base/utils/workers" - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/protocols/snap" - "github.com/ethereum/go-ethereum/event" - notify "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/dnsdisc" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/enr" - "github.com/ethereum/go-ethereum/rpc" - - "github.com/Fantom-foundation/go-opera/ethapi" - "github.com/Fantom-foundation/go-opera/eventcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/basiccheck" - "github.com/Fantom-foundation/go-opera/eventcheck/epochcheck" - "github.com/Fantom-foundation/go-opera/eventcheck/gaspowercheck" - "github.com/Fantom-foundation/go-opera/eventcheck/heavycheck" - "github.com/Fantom-foundation/go-opera/eventcheck/parentscheck" - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/blockproc" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/drivermodule" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/eventmodule" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/evmmodule" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/sealmodule" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/verwatcher" - "github.com/Fantom-foundation/go-opera/gossip/emitter" - "github.com/Fantom-foundation/go-opera/gossip/filters" - "github.com/Fantom-foundation/go-opera/gossip/gasprice" - "github.com/Fantom-foundation/go-opera/gossip/proclogger" - snapsync "github.com/Fantom-foundation/go-opera/gossip/protocols/snap" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/utils/signers/gsignercache" - "github.com/Fantom-foundation/go-opera/utils/txtime" - "github.com/Fantom-foundation/go-opera/utils/wgmutex" - "github.com/Fantom-foundation/go-opera/valkeystore" - "github.com/Fantom-foundation/go-opera/vecmt" -) - -type ServiceFeed struct { - scope notify.SubscriptionScope - - newEpoch notify.Feed - newEmittedEvent notify.Feed - newBlock notify.Feed - newLogs notify.Feed -} - -func (f *ServiceFeed) SubscribeNewEpoch(ch chan<- idx.Epoch) notify.Subscription { - return f.scope.Track(f.newEpoch.Subscribe(ch)) -} - -func (f *ServiceFeed) SubscribeNewEmitted(ch chan<- *inter.EventPayload) notify.Subscription { - return f.scope.Track(f.newEmittedEvent.Subscribe(ch)) -} - -func (f *ServiceFeed) SubscribeNewBlock(ch chan<- evmcore.ChainHeadNotify) notify.Subscription { - return f.scope.Track(f.newBlock.Subscribe(ch)) -} - -func (f *ServiceFeed) SubscribeNewLogs(ch chan<- []*types.Log) notify.Subscription { - return f.scope.Track(f.newLogs.Subscribe(ch)) -} - -type BlockProc struct { - SealerModule blockproc.SealerModule - TxListenerModule blockproc.TxListenerModule - PreTxTransactor blockproc.TxTransactor - PostTxTransactor blockproc.TxTransactor - EventsModule blockproc.ConfirmedEventsModule - EVMModule blockproc.EVM -} - -func DefaultBlockProc() BlockProc { - return BlockProc{ - SealerModule: sealmodule.New(), - TxListenerModule: drivermodule.NewDriverTxListenerModule(), - PreTxTransactor: drivermodule.NewDriverTxPreTransactor(), - PostTxTransactor: drivermodule.NewDriverTxTransactor(), - EventsModule: eventmodule.New(), - EVMModule: evmmodule.New(), - } -} - -// Service implements go-ethereum/node.Service interface. -type Service struct { - config Config - - // server - p2pServer *p2p.Server - Name string - - accountManager *accounts.Manager - - // application - store *Store - engine lachesis.Consensus - dagIndexer *vecmt.Index - engineMu *sync.RWMutex - emitters []*emitter.Emitter - txpool TxPool - heavyCheckReader HeavyCheckReader - gasPowerCheckReader GasPowerCheckReader - checkers *eventcheck.Checkers - uniqueEventIDs uniqueID - - // version watcher - verWatcher *verwatcher.VerWarcher - - blockProcWg sync.WaitGroup - blockProcTasks *workers.Workers - blockProcTasksDone chan struct{} - blockProcModules BlockProc - - blockBusyFlag uint32 - eventBusyFlag uint32 - - feed ServiceFeed - eventMux *event.TypeMux - - gpo *gasprice.Oracle - - // application protocol - handler *handler - - operaDialCandidates enode.Iterator - snapDialCandidates enode.Iterator - - EthAPI *EthAPIBackend - netRPCService *ethapi.PublicNetAPI - - procLogger *proclogger.Logger - - stopped bool - haltCheck func(oldEpoch, newEpoch idx.Epoch, time time.Time) bool - - tflusher PeriodicFlusher - - bootstrapping bool - - logger.Instance -} - -func NewService(stack *node.Node, config Config, store *Store, blockProc BlockProc, - engine lachesis.Consensus, dagIndexer *vecmt.Index, newTxPool func(evmcore.StateReader) TxPool, - haltCheck func(oldEpoch, newEpoch idx.Epoch, age time.Time) bool) (*Service, error) { - if err := config.Validate(); err != nil { - return nil, err - } - - svc, err := newService(config, store, blockProc, engine, dagIndexer, newTxPool) - if err != nil { - return nil, err - } - - svc.p2pServer = stack.Server() - svc.accountManager = stack.AccountManager() - svc.eventMux = stack.EventMux() - svc.EthAPI.SetExtRPCEnabled(stack.Config().ExtRPCEnabled()) - // Create the net API service - svc.netRPCService = ethapi.NewPublicNetAPI(svc.p2pServer, store.GetRules().NetworkID) - svc.haltCheck = haltCheck - - return svc, nil -} - -func newService(config Config, store *Store, blockProc BlockProc, engine lachesis.Consensus, dagIndexer *vecmt.Index, newTxPool func(evmcore.StateReader) TxPool) (*Service, error) { - svc := &Service{ - config: config, - blockProcTasksDone: make(chan struct{}), - Name: fmt.Sprintf("Node-%d", rand.Int()), - store: store, - engine: engine, - blockProcModules: blockProc, - dagIndexer: dagIndexer, - engineMu: new(sync.RWMutex), - uniqueEventIDs: uniqueID{new(big.Int)}, - procLogger: proclogger.NewLogger(), - Instance: logger.New("gossip-service"), - } - - svc.blockProcTasks = workers.New(new(sync.WaitGroup), svc.blockProcTasksDone, 1) - - // load epoch DB - svc.store.loadEpochStore(svc.store.GetEpoch()) - es := svc.store.getEpochStore(svc.store.GetEpoch()) - svc.dagIndexer.Reset(svc.store.GetValidators(), es.table.DagIndex, func(id hash.Event) dag.Event { - return svc.store.GetEvent(id) - }) - - // load caches for mutable values to avoid race condition - svc.store.GetBlockEpochState() - svc.store.GetHighestLamport() - svc.store.GetLastBVs() - svc.store.GetLastEVs() - svc.store.GetLlrState() - svc.store.GetUpgradeHeights() - svc.store.GetGenesisID() - netVerStore := verwatcher.NewStore(store.table.NetworkVersion) - netVerStore.GetNetworkVersion() - netVerStore.GetMissedVersion() - - // create GPO - svc.gpo = gasprice.NewOracle(svc.config.GPO) - - // create checkers - net := store.GetRules() - txSigner := gsignercache.Wrap(types.LatestSignerForChainID(new(big.Int).SetUint64(net.NetworkID))) - svc.heavyCheckReader.Store = store - svc.heavyCheckReader.Pubkeys.Store(readEpochPubKeys(svc.store, svc.store.GetEpoch())) // read pub keys of current epoch from DB - svc.gasPowerCheckReader.Ctx.Store(NewGasPowerContext(svc.store, svc.store.GetValidators(), svc.store.GetEpoch(), net.Economy)) // read gaspower check data from DB - svc.checkers = makeCheckers(config.HeavyCheck, txSigner, &svc.heavyCheckReader, &svc.gasPowerCheckReader, svc.store) - - // create tx pool - stateReader := svc.GetEvmStateReader() - svc.txpool = newTxPool(stateReader) - - // init dialCandidates - dnsclient := dnsdisc.NewClient(dnsdisc.Config{}) - var err error - svc.operaDialCandidates, err = dnsclient.NewIterator(config.OperaDiscoveryURLs...) - if err != nil { - return nil, err - } - svc.snapDialCandidates, err = dnsclient.NewIterator(config.SnapDiscoveryURLs...) - if err != nil { - return nil, err - } - - // create protocol manager - svc.handler, err = newHandler(handlerConfig{ - config: config, - notifier: &svc.feed, - txpool: svc.txpool, - engineMu: svc.engineMu, - checkers: svc.checkers, - s: store, - process: processCallback{ - Event: func(event *inter.EventPayload) error { - done := svc.procLogger.EventConnectionStarted(event, false) - defer done() - return svc.processEvent(event) - }, - SwitchEpochTo: svc.SwitchEpochTo, - PauseEvmSnapshot: svc.PauseEvmSnapshot, - BVs: svc.ProcessBlockVotes, - BR: svc.ProcessFullBlockRecord, - EV: svc.ProcessEpochVote, - ER: svc.ProcessFullEpochRecord, - }, - }) - if err != nil { - return nil, err - } - - rpc.SetExecutionTimeLimit(config.RPCTimeout) - - // create API backend - svc.EthAPI = &EthAPIBackend{false, svc, stateReader, txSigner, config.AllowUnprotectedTxs} - - svc.verWatcher = verwatcher.New(netVerStore) - svc.tflusher = svc.makePeriodicFlusher() - - return svc, nil -} - -// makeCheckers builds event checkers -func makeCheckers(heavyCheckCfg heavycheck.Config, txSigner types.Signer, heavyCheckReader *HeavyCheckReader, gasPowerCheckReader *GasPowerCheckReader, store *Store) *eventcheck.Checkers { - // create signatures checker - heavyCheck := heavycheck.New(heavyCheckCfg, heavyCheckReader, txSigner) - - // create gaspower checker - gaspowerCheck := gaspowercheck.New(gasPowerCheckReader) - - return &eventcheck.Checkers{ - Basiccheck: basiccheck.New(), - Epochcheck: epochcheck.New(store), - Parentscheck: parentscheck.New(), - Heavycheck: heavyCheck, - Gaspowercheck: gaspowerCheck, - } -} - -// makePeriodicFlusher makes PeriodicFlusher -func (s *Service) makePeriodicFlusher() PeriodicFlusher { - // Normally the diffs are committed by message processing. Yet, since we have async EVM snapshots generation, - // we need to periodically commit its data - return PeriodicFlusher{ - period: 10 * time.Millisecond, - callback: PeriodicFlusherCallaback{ - busy: func() bool { - // try to lock engineMu/blockProcWg pair as rarely as possible to not hurt - // events/blocks pipeline concurrency - return atomic.LoadUint32(&s.eventBusyFlag) != 0 || atomic.LoadUint32(&s.blockBusyFlag) != 0 - }, - commitNeeded: func() bool { - // use slightly higher size threshold to avoid locking the mutex/wg pair and hurting events/blocks concurrency - // PeriodicFlusher should mostly commit only data generated by async EVM snapshots generation - return s.store.isCommitNeeded(1200, 1000) - }, - commit: func() { - s.engineMu.Lock() - defer s.engineMu.Unlock() - // Note: blockProcWg.Wait() is already called by s.commit - if s.store.isCommitNeeded(1200, 1000) { - s.commit(false) - } - }, - }, - wg: sync.WaitGroup{}, - quit: make(chan struct{}), - } -} - -func (s *Service) EmitterWorld(signer valkeystore.SignerI) emitter.World { - return emitter.World{ - External: &emitterWorld{ - emitterWorldProc: emitterWorldProc{s}, - emitterWorldRead: emitterWorldRead{s.store}, - WgMutex: wgmutex.New(s.engineMu, &s.blockProcWg), - }, - TxPool: s.txpool, - Signer: signer, - TxSigner: s.EthAPI.signer, - } -} - -// RegisterEmitter must be called before service is started -func (s *Service) RegisterEmitter(em *emitter.Emitter) { - txtime.Enabled = true // enable tracking of tx times - s.emitters = append(s.emitters, em) -} - -// MakeProtocols constructs the P2P protocol definitions for `opera`. -func MakeProtocols(svc *Service, backend *handler, disc enode.Iterator) []p2p.Protocol { - protocols := make([]p2p.Protocol, len(ProtocolVersions)) - for i, version := range ProtocolVersions { - version := version // Closure - - protocols[i] = p2p.Protocol{ - Name: ProtocolName, - Version: version, - Length: protocolLengths[version], - Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { - // wait until handler has started - backend.started.Wait() - peer := newPeer(version, p, rw, backend.config.Protocol.PeerCache) - defer peer.Close() - - select { - case <-backend.quitSync: - return p2p.DiscQuitting - default: - backend.wg.Add(1) - defer backend.wg.Done() - return backend.handle(peer) - } - }, - NodeInfo: func() interface{} { - return backend.NodeInfo() - }, - PeerInfo: func(id enode.ID) interface{} { - if p := backend.peers.Peer(id.String()); p != nil { - return p.Info() - } - return nil - }, - Attributes: []enr.Entry{currentENREntry(svc)}, - DialCandidates: disc, - } - } - return protocols -} - -// Protocols returns protocols the service can communicate on. -func (s *Service) Protocols() []p2p.Protocol { - protos := append( - MakeProtocols(s, s.handler, s.operaDialCandidates), - snap.MakeProtocols((*snapHandler)(s.handler), s.snapDialCandidates)...) - return protos -} - -// APIs returns api methods the service wants to expose on rpc channels. -func (s *Service) APIs() []rpc.API { - apis := ethapi.GetAPIs(s.EthAPI) - - apis = append(apis, []rpc.API{ - { - Namespace: "eth", - Version: "1.0", - Service: NewPublicEthereumAPI(s), - Public: true, - }, { - Namespace: "eth", - Version: "1.0", - Service: filters.NewPublicFilterAPI(s.EthAPI, s.config.FilterAPI), - Public: true, - }, { - Namespace: "eth", - Version: "1.0", - Service: snapsync.NewPublicDownloaderAPI(s.handler.snapLeecher, s.eventMux), - Public: true, - }, { - Namespace: "net", - Version: "1.0", - Service: s.netRPCService, - Public: true, - }, - }...) - - return apis -} - -// Start method invoked when the node is ready to start the service. -func (s *Service) Start() error { - s.gpo.Start(&GPOBackend{s.store, s.txpool}) - // start tflusher before starting snapshots generation - s.tflusher.Start() - // start snapshots generation - if s.store.evm.IsEvmSnapshotPaused() && !s.config.AllowSnapsync { - return errors.New("cannot halt snapsync and start fullsync") - } - s.RecoverEVM() - root := s.store.GetBlockState().FinalizedStateRoot - if !s.store.evm.HasStateDB(root) { - if !s.config.AllowSnapsync { - return errors.New("fullsync isn't possible because state root is missing") - } - root = hash.Zero - } - _ = s.store.GenerateSnapshotAt(common.Hash(root), true) - - // start blocks processor - s.blockProcTasks.Start(1) - - // start p2p - StartENRUpdater(s, s.p2pServer.LocalNode()) - s.handler.Start(s.p2pServer.MaxPeers) - - // start emitters - for _, em := range s.emitters { - em.Start() - } - - s.verWatcher.Start() - - if s.haltCheck != nil && s.haltCheck(s.store.GetEpoch(), s.store.GetEpoch(), s.store.GetBlockState().LastBlock.Time.Time()) { - // halt syncing - s.stopped = true - } - - return nil -} - -// WaitBlockEnd waits until parallel block processing is complete (if any) -func (s *Service) WaitBlockEnd() { - s.blockProcWg.Wait() -} - -// Stop method invoked when the node terminates the service. -func (s *Service) Stop() error { - defer log.Info("X1 service stopped") - s.verWatcher.Stop() - for _, em := range s.emitters { - em.Stop() - } - - // Stop all the peer-related stuff first. - s.operaDialCandidates.Close() - s.snapDialCandidates.Close() - - s.handler.Stop() - s.feed.scope.Close() - s.eventMux.Stop() - s.gpo.Stop() - // it's safe to stop tflusher only before locking engineMu - s.tflusher.Stop() - - // flush the state at exit, after all the routines stopped - s.engineMu.Lock() - defer s.engineMu.Unlock() - s.stopped = true - - s.blockProcWg.Wait() - close(s.blockProcTasksDone) - s.store.evm.Flush(s.store.GetBlockState()) - return s.store.Commit() -} - -// AccountManager return node's account manager -func (s *Service) AccountManager() *accounts.Manager { - return s.accountManager -} diff --git a/evm/go-x1/gossip/sfc_test.go b/evm/go-x1/gossip/sfc_test.go deleted file mode 100644 index 2b4b7c5..0000000 --- a/evm/go-x1/gossip/sfc_test.go +++ /dev/null @@ -1,226 +0,0 @@ -package gossip - -// compile SFC with truffle -//go:generate bash -c "cd ../../x1-sfc && git checkout HEAD" -//go:generate bash -c "docker run --name go-x1-sfc-compiler -v $(pwd)/contract/solc:/src/build/contracts -v $(pwd)/../../x1-sfc:/src -w /src node:10.5.0 bash -c 'export NPM_CONFIG_PREFIX=~; npm install --no-save; npm install --no-save truffle@5.1.4' && docker commit go-x1-sfc-compiler go-x1-sfc-compiler-image && docker rm go-x1-sfc-compiler" -//go:generate bash -c "docker run --rm -v $(pwd)/contract/solc:/src/build/contracts -v $(pwd)/../../x1-sfc:/src -w /src go-x1-sfc-compiler-image bash -c 'export NPM_CONFIG_PREFIX=~; rm -f /src/build/contracts/*json; npm run build'" -//go:generate bash -c "cd ./contract/solc && for f in SFC.json SFCLib.json; do jq -j .bytecode $DOLLAR{f} > $DOLLAR{f%.json}.bin; jq -j .deployedBytecode $DOLLAR{f} > $DOLLAR{f%.json}.bin-runtime; jq -c .abi $DOLLAR{f} > $DOLLAR{f%.json}.abi; done" -//go:generate bash -c "docker run --rm -v $(pwd)/contract/solc:/src/build/contracts -v $(pwd)/../../x1-sfc:/src -w /src go-x1-sfc-compiler-image bash -c 'export NPM_CONFIG_PREFIX=~; sed -i s/runs:\\ 200,/runs:\\ 10000,/ /src/truffle-config.js; rm -f /src/build/contracts/*json; npm run build'" -//go:generate bash -c "cd ../../x1-sfc && git checkout -- truffle-config.js; docker rmi go-x1-sfc-compiler-image" -//go:generate bash -c "cd ./contract/solc && for f in NetworkInitializer.json NodeDriver.json NodeDriverAuth.json; do jq -j .bytecode $DOLLAR{f} > $DOLLAR{f%.json}.bin; jq -j .deployedBytecode $DOLLAR{f} > $DOLLAR{f%.json}.bin-runtime; jq -c .abi $DOLLAR{f} > $DOLLAR{f%.json}.abi; done" - -// wrap SFC with golang -//go:generate mkdir -p ./contract/sfc100 -//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen --bin=./contract/solc/SFC.bin --abi=./contract/solc/SFC.abi --pkg=sfc100 --type=Contract --out=contract/sfc100/contract.go -//go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/SFC.bin-runtime; echo '\"') >> contract/sfc100/contract.go" -// wrap SFC lib with golang -//go:generate mkdir -p ./contract/sfclib100 -//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen --bin=./contract/solc/SFCLib.bin --abi=./contract/solc/SFCLib.abi --pkg=sfclib100 --type=Contract --out=contract/sfclib100/contract.go -//go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/SFCLib.bin-runtime; echo '\"') >> contract/sfclib100/contract.go" -// wrap NetworkInitializer with golang -//go:generate mkdir -p ./contract/netinit100 -//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen --bin=./contract/solc/NetworkInitializer.bin --abi=./contract/solc/NetworkInitializer.abi --pkg=netinit100 --type=Contract --out=contract/netinit100/contract.go -//go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/NetworkInitializer.bin-runtime; echo '\"') >> contract/netinit100/contract.go" -// wrap NodeDriver with golang -//go:generate mkdir -p ./contract/driver100 -//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen --bin=./contract/solc/NodeDriver.bin --abi=./contract/solc/NodeDriver.abi --pkg=driver100 --type=Contract --out=contract/driver100/contract.go -//go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/NodeDriver.bin-runtime; echo '\"') >> contract/driver100/contract.go" -// wrap NodeDriverAuth with golang -//go:generate mkdir -p ./contract/driverauth100 -//go:generate go run github.com/ethereum/go-ethereum/cmd/abigen --bin=./contract/solc/NodeDriverAuth.bin --abi=./contract/solc/NodeDriverAuth.abi --pkg=driverauth100 --type=Contract --out=contract/driverauth100/contract.go -//go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/NodeDriverAuth.bin-runtime; echo '\"') >> contract/driverauth100/contract.go" - -import ( - "fmt" - "math/big" - "testing" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/gossip/contract/driver100" - "github.com/Fantom-foundation/go-opera/gossip/contract/driverauth100" - "github.com/Fantom-foundation/go-opera/gossip/contract/netinit100" - "github.com/Fantom-foundation/go-opera/gossip/contract/sfc100" - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver" - "github.com/Fantom-foundation/go-opera/opera/contracts/driverauth" - "github.com/Fantom-foundation/go-opera/opera/contracts/evmwriter" - "github.com/Fantom-foundation/go-opera/opera/contracts/netinit" - "github.com/Fantom-foundation/go-opera/opera/contracts/sfc" - "github.com/Fantom-foundation/go-opera/utils" -) - -func TestSFC(t *testing.T) { - logger.SetTestMode(t) - logger.SetLevel("debug") - - env := newTestEnv(2, 3) - defer env.Close() - - var ( - sfc10 *sfc100.Contract - err error - ) - - authDriver10, err := driverauth100.NewContract(driverauth.ContractAddress, env) - require.NoError(t, err) - rootDriver10, err := driver100.NewContract(driver.ContractAddress, env) - require.NoError(t, err) - - admin := idx.ValidatorID(1) - adminAddr := env.Address(admin) - - _ = true && - t.Run("Genesis SFC", func(t *testing.T) { - require := require.New(t) - - exp := sfc.GetContractBin() - got, err := env.CodeAt(nil, sfc.ContractAddress, nil) - require.NoError(err) - require.Equal(exp, got, "genesis SFC contract") - require.Equal(exp, hexutil.MustDecode(sfc100.ContractBinRuntime), "genesis SFC contract version") - }) && - t.Run("Genesis Driver", func(t *testing.T) { - require := require.New(t) - - exp := driver.GetContractBin() - got, err := env.CodeAt(nil, driver.ContractAddress, nil) - require.NoError(err) - require.Equal(exp, got, "genesis Driver contract") - require.Equal(exp, hexutil.MustDecode(driver100.ContractBinRuntime), "genesis Driver contract version") - }) && - t.Run("Genesis DriverAuth", func(t *testing.T) { - require := require.New(t) - - exp := driverauth.GetContractBin() - got, err := env.CodeAt(nil, driverauth.ContractAddress, nil) - require.NoError(err) - require.Equal(exp, got, "genesis DriverAuth contract") - require.Equal(exp, hexutil.MustDecode(driverauth100.ContractBinRuntime), "genesis DriverAuth contract version") - }) && - t.Run("Network initializer", func(t *testing.T) { - require := require.New(t) - - exp := netinit.GetContractBin() - got, err := env.CodeAt(nil, netinit.ContractAddress, nil) - require.NoError(err) - require.NotEmpty(exp, "genesis NetworkInitializer contract") - require.Empty(got, "genesis NetworkInitializer should be destructed") - require.Equal(exp, hexutil.MustDecode(netinit100.ContractBinRuntime), "genesis NetworkInitializer contract version") - }) && - t.Run("Builtin EvmWriter", func(t *testing.T) { - require := require.New(t) - - exp := []byte{0} - got, err := env.CodeAt(nil, evmwriter.ContractAddress, nil) - require.NoError(err) - require.Equal(exp, got, "builtin EvmWriter contract") - }) && - t.Run("Some transfers I", func(t *testing.T) { - circleTransfers(t, env, 1) - }) && - t.Run("Check owners", func(t *testing.T) { - require := require.New(t) - - opts := env.ReadOnly() - opts.From = adminAddr - - isOwn, err := authDriver10.IsOwner(opts) - require.NoError(err) - require.True(isOwn) - }) && - t.Run("SFC upgrade", func(t *testing.T) { - require := require.New(t) - - // create new - rr, err := env.ApplyTxs(nextEpoch, - env.Contract(admin, utils.ToFtm(0), sfc100.ContractBin), - ) - require.NoError(err) - require.Equal(1, rr.Len()) - require.Equal(types.ReceiptStatusSuccessful, rr[0].Status) - newImpl := rr[0].ContractAddress - require.NotEqual(sfc.ContractAddress, newImpl) - newSfcContractBinRuntime, err := env.CodeAt(nil, newImpl, nil) - require.NoError(err) - require.Equal(hexutil.MustDecode(sfc100.ContractBinRuntime), newSfcContractBinRuntime) - - tx, err := authDriver10.CopyCode(env.Pay(admin), sfc.ContractAddress, newImpl) - require.NoError(err) - rr, err = env.ApplyTxs(sameEpoch, tx) - require.NoError(err) - require.Equal(1, rr.Len()) - require.Equal(types.ReceiptStatusSuccessful, rr[0].Status) - got, err := env.CodeAt(nil, sfc.ContractAddress, nil) - require.NoError(err) - require.Equal(newSfcContractBinRuntime, got, "new SFC contract") - - sfc10, err = sfc100.NewContract(sfc.ContractAddress, env) - require.NoError(err) - sfcEpoch, err := sfc10.ContractCaller.CurrentEpoch(env.ReadOnly()) - require.NoError(err) - require.Equal(0, sfcEpoch.Cmp(big.NewInt(3)), "current SFC epoch %s", sfcEpoch.String()) - }) - - t.Run("Direct driver", func(t *testing.T) { - require := require.New(t) - - // create new - anyContractBin := driver100.ContractBin - rr, err := env.ApplyTxs(nextEpoch, - env.Contract(admin, utils.ToFtm(0), anyContractBin), - ) - require.NoError(err) - require.Equal(1, rr.Len()) - require.Equal(types.ReceiptStatusSuccessful, rr[0].Status) - newImpl := rr[0].ContractAddress - - tx, err := rootDriver10.CopyCode(env.Pay(admin), sfc.ContractAddress, newImpl) - require.NoError(err) - rr, err = env.ApplyTxs(sameEpoch, tx) - require.NoError(err) - require.Equal(1, rr.Len()) - require.NotEqual(types.ReceiptStatusSuccessful, rr[0].Status) - }) - -} - -func circleTransfers(t *testing.T, env *testEnv, count uint64) { - require := require.New(t) - validatorsNum := env.store.GetValidators().Len() - - // save start balances - balances := make([]*big.Int, validatorsNum) - for i := range balances { - balances[i] = env.State().GetBalance(env.Address(idx.ValidatorID(i + 1))) - } - - for i := uint64(0); i < count; i++ { - // transfers - txs := make([]*types.Transaction, validatorsNum) - for i := idx.Validator(0); i < validatorsNum; i++ { - from := (i) % validatorsNum - to := (i + 1) % validatorsNum - txs[i] = env.Transfer(idx.ValidatorID(from+1), idx.ValidatorID(to+1), utils.ToFtm(100)) - } - - rr, err := env.ApplyTxs(sameEpoch, txs...) - require.NoError(err) - for i, r := range rr { - fee := big.NewInt(0).Mul(new(big.Int).SetUint64(r.GasUsed), txs[i].GasPrice()) - balances[i] = big.NewInt(0).Sub(balances[i], fee) - } - } - - // check balances - for i := range balances { - require.Equal( - balances[i], - env.State().GetBalance(env.Address(idx.ValidatorID(i+1))), - fmt.Sprintf("account%d", i), - ) - } -} diff --git a/evm/go-x1/gossip/store.go b/evm/go-x1/gossip/store.go deleted file mode 100644 index 3925a61..0000000 --- a/evm/go-x1/gossip/store.go +++ /dev/null @@ -1,301 +0,0 @@ -package gossip - -import ( - "sync" - "sync/atomic" - "time" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/flushable" - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" - "github.com/Fantom-foundation/lachesis-base/utils/wlru" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/utils/adapters/snap2kvdb" - "github.com/Fantom-foundation/go-opera/utils/dbutil/switchable" - "github.com/Fantom-foundation/go-opera/utils/eventid" - "github.com/Fantom-foundation/go-opera/utils/randat" - "github.com/Fantom-foundation/go-opera/utils/rlpstore" -) - -// Store is a node persistent storage working over physical key-value database. -type Store struct { - dbs kvdb.FlushableDBProducer - cfg StoreConfig - - snapshotedEVMDB *switchable.Snapshot - evm *evmstore.Store - table struct { - Version kvdb.Store `table:"_"` - - // Main DAG tables - BlockEpochState kvdb.Store `table:"D"` - BlockEpochStateHistory kvdb.Store `table:"h"` - Events kvdb.Store `table:"e"` - Blocks kvdb.Store `table:"b"` - EpochBlocks kvdb.Store `table:"P"` - Genesis kvdb.Store `table:"g"` - UpgradeHeights kvdb.Store `table:"U"` - - // P2P-only - HighestLamport kvdb.Store `table:"l"` - - // Network version - NetworkVersion kvdb.Store `table:"V"` - - // API-only - BlockHashes kvdb.Store `table:"B"` - - LlrState kvdb.Store `table:"S"` - LlrBlockResults kvdb.Store `table:"R"` - LlrEpochResults kvdb.Store `table:"Q"` - LlrBlockVotes kvdb.Store `table:"T"` - LlrBlockVotesIndex kvdb.Store `table:"J"` - LlrEpochVotes kvdb.Store `table:"E"` - LlrEpochVoteIndex kvdb.Store `table:"I"` - LlrLastBlockVotes kvdb.Store `table:"G"` - LlrLastEpochVote kvdb.Store `table:"F"` - } - - prevFlushTime time.Time - - epochStore atomic.Value - - cache struct { - Events *wlru.Cache `cache:"-"` // store by pointer - EventIDs *eventid.Cache - EventsHeaders *wlru.Cache `cache:"-"` // store by pointer - Blocks *wlru.Cache `cache:"-"` // store by pointer - BlockHashes *wlru.Cache `cache:"-"` // store by value - BRHashes *wlru.Cache `cache:"-"` // store by value - EvmBlocks *wlru.Cache `cache:"-"` // store by pointer - BlockEpochStateHistory *wlru.Cache `cache:"-"` // store by pointer - BlockEpochState atomic.Value // store by value - HighestLamport atomic.Value // store by value - LastBVs atomic.Value // store by pointer - LastEV atomic.Value // store by pointer - LlrState atomic.Value // store by value - KvdbEvmSnap atomic.Value // store by pointer - UpgradeHeights atomic.Value // store by pointer - Genesis atomic.Value // store by value - LlrBlockVotesIndex *VotesCache // store by pointer - LlrEpochVoteIndex *VotesCache // store by pointer - } - - mutex struct { - WriteLlrState sync.Mutex - } - - rlp rlpstore.Helper - - logger.Instance -} - -// NewMemStore creates store over memory map. -func NewMemStore() *Store { - mems := memorydb.NewProducer("") - dbs := flushable.NewSyncedPool(mems, []byte{0}) - cfg := LiteStoreConfig() - - return NewStore(dbs, cfg) -} - -// NewStore creates store over key-value db. -func NewStore(dbs kvdb.FlushableDBProducer, cfg StoreConfig) *Store { - s := &Store{ - dbs: dbs, - cfg: cfg, - Instance: logger.New("gossip-store"), - prevFlushTime: time.Now(), - rlp: rlpstore.Helper{logger.New("rlp")}, - } - - err := table.OpenTables(&s.table, dbs, "gossip") - if err != nil { - log.Crit("Failed to open DB", "name", "gossip", "err", err) - } - - s.initCache() - s.evm = evmstore.NewStore(dbs, cfg.EVM) - - if err := s.migrateData(); err != nil { - s.Log.Crit("Failed to migrate Gossip DB", "err", err) - } - - return s -} - -func (s *Store) initCache() { - s.cache.Events = s.makeCache(s.cfg.Cache.EventsSize, s.cfg.Cache.EventsNum) - s.cache.Blocks = s.makeCache(s.cfg.Cache.BlocksSize, s.cfg.Cache.BlocksNum) - - blockHashesNum := s.cfg.Cache.BlocksNum - blockHashesCacheSize := nominalSize * uint(blockHashesNum) - s.cache.BlockHashes = s.makeCache(blockHashesCacheSize, blockHashesNum) - s.cache.BRHashes = s.makeCache(blockHashesCacheSize, blockHashesNum) - - eventsHeadersNum := s.cfg.Cache.EventsNum - eventsHeadersCacheSize := nominalSize * uint(eventsHeadersNum) - s.cache.EventsHeaders = s.makeCache(eventsHeadersCacheSize, eventsHeadersNum) - - s.cache.EventIDs = eventid.NewCache(s.cfg.Cache.EventsIDsNum) - - blockEpochStatesNum := s.cfg.Cache.BlockEpochStateNum - blockEpochStatesSize := nominalSize * uint(blockEpochStatesNum) - s.cache.BlockEpochStateHistory = s.makeCache(blockEpochStatesSize, blockEpochStatesNum) - - s.cache.LlrBlockVotesIndex = NewVotesCache(s.cfg.Cache.LlrBlockVotesIndexes, s.flushLlrBlockVoteWeight) - s.cache.LlrEpochVoteIndex = NewVotesCache(s.cfg.Cache.LlrEpochVotesIndexes, s.flushLlrEpochVoteWeight) -} - -// Close closes underlying database. -func (s *Store) Close() { - setnil := func() interface{} { - return nil - } - - if s.snapshotedEVMDB != nil { - s.snapshotedEVMDB.Release() - } - _ = table.CloseTables(&s.table) - table.MigrateTables(&s.table, nil) - table.MigrateCaches(&s.cache, setnil) - - _ = s.closeEpochStore() - s.evm.Close() -} - -func (s *Store) IsCommitNeeded() bool { - // randomize flushing criteria for each epoch so that nodes would desynchronize flushes - ratio := 900 + randat.RandAt(uint64(s.GetEpoch()))%100 - return s.isCommitNeeded(ratio, ratio) -} - -func (s *Store) isCommitNeeded(sc, tc uint64) bool { - period := s.cfg.MaxNonFlushedPeriod * time.Duration(sc) / 1000 - size := (uint64(s.cfg.MaxNonFlushedSize) / 2) * tc / 1000 - return time.Since(s.prevFlushTime) > period || - uint64(s.dbs.NotFlushedSizeEst()) > size -} - -// commitEVM commits EVM storage -func (s *Store) commitEVM(flush bool) { - bs := s.GetBlockState() - err := s.evm.Commit(bs.LastBlock.Idx, bs.FinalizedStateRoot, flush) - if err != nil { - s.Log.Crit("Failed to commit EVM storage", "err", err) - } - s.evm.Cap() -} - -func (s *Store) cleanCommitEVM() { - err := s.evm.CleanCommit(s.GetBlockState()) - if err != nil { - s.Log.Crit("Failed to commit EVM storage", "err", err) - } - s.evm.Cap() -} - -func (s *Store) GenerateSnapshotAt(root common.Hash, async bool) (err error) { - err = s.generateSnapshotAt(s.evm, root, true, async) - if err != nil { - s.Log.Error("EVM snapshot", "at", root, "err", err) - } else { - gen, _ := s.evm.Snaps.Generating() - s.Log.Info("EVM snapshot", "at", root, "generating", gen) - } - return err -} - -func (s *Store) generateSnapshotAt(evmStore *evmstore.Store, root common.Hash, rebuild, async bool) (err error) { - return evmStore.GenerateEvmSnapshot(root, rebuild, async) -} - -// Commit changes. -func (s *Store) Commit() error { - s.FlushBlockEpochState() - s.FlushHighestLamport() - s.FlushLastBVs() - s.FlushLastEV() - s.FlushLlrState() - s.cache.LlrBlockVotesIndex.FlushMutated(s.flushLlrBlockVoteWeight) - s.cache.LlrEpochVoteIndex.FlushMutated(s.flushLlrEpochVoteWeight) - es := s.getAnyEpochStore() - if es != nil { - es.FlushHeads() - es.FlushLastEvents() - } - return s.flushDBs() -} - -func (s *Store) flushDBs() error { - s.prevFlushTime = time.Now() - flushID := bigendian.Uint64ToBytes(uint64(s.prevFlushTime.UnixNano())) - return s.dbs.Flush(flushID) -} - -func (s *Store) EvmStore() *evmstore.Store { - return s.evm -} - -func (s *Store) CaptureEvmKvdbSnapshot() { - if s.evm.Snaps == nil { - return - } - gen, err := s.evm.Snaps.Generating() - if err != nil { - s.Log.Error("Failed to check EVM snapshot generation", "err", err) - return - } - if gen { - return - } - newEvmKvdbSnap, err := s.evm.EVMDB().GetSnapshot() - if err != nil { - s.Log.Error("Failed to initialize frozen KVDB", "err", err) - return - } - if s.snapshotedEVMDB == nil { - s.snapshotedEVMDB = switchable.Wrap(newEvmKvdbSnap) - } else { - old := s.snapshotedEVMDB.SwitchTo(newEvmKvdbSnap) - // release only after DB is atomically switched - if old != nil { - old.Release() - } - } - newStore := s.evm.ResetWithEVMDB(snap2kvdb.Wrap(s.snapshotedEVMDB)) - newStore.Snaps = nil - root := s.GetBlockState().FinalizedStateRoot - err = s.generateSnapshotAt(newStore, common.Hash(root), false, false) - if err != nil { - s.Log.Error("Failed to initialize EVM snapshot for frozen KVDB", "err", err) - return - } - s.cache.KvdbEvmSnap.Store(newStore) -} - -func (s *Store) LastKvdbEvmSnapshot() *evmstore.Store { - if v := s.cache.KvdbEvmSnap.Load(); v != nil { - return v.(*evmstore.Store) - } - return s.evm -} - -/* - * Utils: - */ - -func (s *Store) makeCache(weight uint, size int) *wlru.Cache { - cache, err := wlru.New(weight, size) - if err != nil { - s.Log.Crit("Failed to create LRU cache", "err", err) - return nil - } - return cache -} diff --git a/evm/go-x1/gossip/store_activation_heights.go b/evm/go-x1/gossip/store_activation_heights.go deleted file mode 100644 index 8191778..0000000 --- a/evm/go-x1/gossip/store_activation_heights.go +++ /dev/null @@ -1,27 +0,0 @@ -package gossip - -import ( - "github.com/Fantom-foundation/go-opera/opera" -) - -func (s *Store) AddUpgradeHeight(h opera.UpgradeHeight) { - orig := s.GetUpgradeHeights() - // allocate new memory to avoid race condition in cache - cp := make([]opera.UpgradeHeight, 0, len(orig)+1) - cp = append(append(cp, orig...), h) - - s.rlp.Set(s.table.UpgradeHeights, []byte{}, cp) - s.cache.UpgradeHeights.Store(cp) -} - -func (s *Store) GetUpgradeHeights() []opera.UpgradeHeight { - if v := s.cache.UpgradeHeights.Load(); v != nil { - return v.([]opera.UpgradeHeight) - } - hh, ok := s.rlp.Get(s.table.UpgradeHeights, []byte{}, &[]opera.UpgradeHeight{}).(*[]opera.UpgradeHeight) - if !ok { - return []opera.UpgradeHeight{} - } - s.cache.UpgradeHeights.Store(*hh) - return *hh -} diff --git a/evm/go-x1/gossip/store_block.go b/evm/go-x1/gossip/store_block.go deleted file mode 100644 index 1f22318..0000000 --- a/evm/go-x1/gossip/store_block.go +++ /dev/null @@ -1,223 +0,0 @@ -package gossip - -import ( - "math" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/inter" -) - -func (s *Store) GetGenesisID() *hash.Hash { - if v := s.cache.Genesis.Load(); v != nil { - val := v.(hash.Hash) - return &val - } - valBytes, err := s.table.Genesis.Get([]byte("g")) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if len(valBytes) == 0 { - return nil - } - val := hash.BytesToHash(valBytes) - s.cache.Genesis.Store(val) - return &val -} - -func (s *Store) fakeGenesisHash() hash.Event { - fakeGenesisHash := hash.Event(*s.GetGenesisID()) - for i := range fakeGenesisHash[:8] { - fakeGenesisHash[i] = 0 - } - return fakeGenesisHash -} - -func (s *Store) SetGenesisID(val hash.Hash) { - err := s.table.Genesis.Put([]byte("g"), val.Bytes()) - if err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } - s.cache.Genesis.Store(val) -} - -// SetBlock stores chain block. -func (s *Store) SetBlock(n idx.Block, b *inter.Block) { - s.rlp.Set(s.table.Blocks, n.Bytes(), b) - - // Add to LRU cache. - s.cache.Blocks.Add(n, b, uint(b.EstimateSize())) -} - -// GetBlock returns stored block. -func (s *Store) GetBlock(n idx.Block) *inter.Block { - if n == 0 { - // fake genesis block for compatibility with web3 - return &inter.Block{ - Time: evmcore.FakeGenesisTime - 1, - Atropos: s.fakeGenesisHash(), - } - } - // Get block from LRU cache first. - if c, ok := s.cache.Blocks.Get(n); ok { - return c.(*inter.Block) - } - - block, _ := s.rlp.Get(s.table.Blocks, n.Bytes(), &inter.Block{}).(*inter.Block) - - // Add to LRU cache. - if block != nil { - s.cache.Blocks.Add(n, block, uint(block.EstimateSize())) - } - - return block -} - -func (s *Store) HasBlock(n idx.Block) bool { - has, _ := s.table.Blocks.Has(n.Bytes()) - return has -} - -func (s *Store) ForEachBlock(fn func(index idx.Block, block *inter.Block)) { - it := s.table.Blocks.NewIterator(nil, nil) - defer it.Release() - for it.Next() { - var block inter.Block - err := rlp.DecodeBytes(it.Value(), &block) - if err != nil { - s.Log.Crit("Failed to decode block", "err", err) - } - fn(idx.BytesToBlock(it.Key()), &block) - } -} - -// SetBlockIndex stores chain block index. -func (s *Store) SetBlockIndex(id hash.Event, n idx.Block) { - if err := s.table.BlockHashes.Put(id.Bytes(), n.Bytes()); err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } - - s.cache.BlockHashes.Add(id, n, nominalSize) -} - -// GetBlockIndex returns stored block index. -func (s *Store) GetBlockIndex(id hash.Event) *idx.Block { - nVal, ok := s.cache.BlockHashes.Get(id) - if ok { - n, ok := nVal.(idx.Block) - if ok { - return &n - } - } - - buf, err := s.table.BlockHashes.Get(id.Bytes()) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if buf == nil { - if id == s.fakeGenesisHash() { - zero := idx.Block(0) - return &zero - } - return nil - } - n := idx.BytesToBlock(buf) - - s.cache.BlockHashes.Add(id, n, nominalSize) - - return &n -} - -// SetGenesisBlockIndex stores genesis block index. -func (s *Store) SetGenesisBlockIndex(n idx.Block) { - if err := s.table.Genesis.Put([]byte("i"), n.Bytes()); err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } -} - -// GetGenesisBlockIndex returns stored genesis block index. -func (s *Store) GetGenesisBlockIndex() *idx.Block { - buf, err := s.table.Genesis.Get([]byte("i")) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if buf == nil { - return nil - } - n := idx.BytesToBlock(buf) - - return &n -} - -func (s *Store) GetGenesisTime() inter.Timestamp { - n := s.GetGenesisBlockIndex() - if n == nil { - return 0 - } - block := s.GetBlock(*n) - if block == nil { - return 0 - } - return block.Time -} - -func (s *Store) SetEpochBlock(b idx.Block, e idx.Epoch) { - err := s.table.EpochBlocks.Put((math.MaxUint64 - b).Bytes(), e.Bytes()) - if err != nil { - s.Log.Crit("Failed to set key-value", "err", err) - } -} - -func (s *Store) FindBlockEpoch(b idx.Block) idx.Epoch { - if c, ok := s.cache.Blocks.Get(b); ok { - return c.(*inter.Block).Atropos.Epoch() - } - - it := s.table.EpochBlocks.NewIterator(nil, (math.MaxUint64 - b).Bytes()) - defer it.Release() - if !it.Next() { - return 0 - } - return idx.BytesToEpoch(it.Value()) -} - -func (s *Store) GetBlockTxs(n idx.Block, block *inter.Block) types.Transactions { - if cached := s.evm.GetCachedEvmBlock(n); cached != nil { - return cached.Transactions - } - - transactions := make(types.Transactions, 0, len(block.Txs)+len(block.InternalTxs)+len(block.Events)*10) - for _, txid := range block.InternalTxs { - tx := s.evm.GetTx(txid) - if tx == nil { - log.Crit("Internal tx not found", "tx", txid.String()) - continue - } - transactions = append(transactions, tx) - } - for _, txid := range block.Txs { - tx := s.evm.GetTx(txid) - if tx == nil { - log.Crit("Tx not found", "tx", txid.String()) - continue - } - transactions = append(transactions, tx) - } - for _, id := range block.Events { - e := s.GetEventPayload(id) - if e == nil { - log.Crit("Block event not found", "event", id.String()) - continue - } - transactions = append(transactions, e.Txs()...) - } - - transactions = inter.FilterSkippedTxs(transactions, block.SkippedTxs) - - return transactions -} diff --git a/evm/go-x1/gossip/store_decided_state.go b/evm/go-x1/gossip/store_decided_state.go deleted file mode 100644 index 7ad55b8..0000000 --- a/evm/go-x1/gossip/store_decided_state.go +++ /dev/null @@ -1,167 +0,0 @@ -package gossip - -import ( - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/ethereum/go-ethereum/log" - ethparams "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/opera" -) - -const sKey = "s" - -type BlockEpochState struct { - BlockState *iblockproc.BlockState - EpochState *iblockproc.EpochState -} - -// TODO propose to pass bs, es arguments by pointer -func (s *Store) SetHistoryBlockEpochState(epoch idx.Epoch, bs iblockproc.BlockState, es iblockproc.EpochState) { - bs, es = bs.Copy(), es.Copy() - bes := &BlockEpochState{ - BlockState: &bs, - EpochState: &es, - } - // Write to the DB - s.rlp.Set(s.table.BlockEpochStateHistory, epoch.Bytes(), bes) - // Save to the LRU cache - s.cache.BlockEpochStateHistory.Add(epoch, bes, nominalSize) -} - -func (s *Store) GetHistoryBlockEpochState(epoch idx.Epoch) (*iblockproc.BlockState, *iblockproc.EpochState) { - // Get HistoryBlockEpochState from LRU cache first. - if v, ok := s.cache.BlockEpochStateHistory.Get(epoch); ok { - bes := v.(*BlockEpochState) - if bes.EpochState.Epoch == epoch { - bs := bes.BlockState.Copy() - es := bes.EpochState.Copy() - return &bs, &es - } - } - // read from DB - v, ok := s.rlp.Get(s.table.BlockEpochStateHistory, epoch.Bytes(), &BlockEpochState{}).(*BlockEpochState) - if !ok { - return nil, nil - } - // Save to the LRU cache - s.cache.BlockEpochStateHistory.Add(epoch, v, nominalSize) - bs := v.BlockState.Copy() - es := v.EpochState.Copy() - return &bs, &es -} - -func (s *Store) ForEachHistoryBlockEpochState(fn func(iblockproc.BlockState, iblockproc.EpochState) bool) { - it := s.table.BlockEpochStateHistory.NewIterator(nil, nil) - defer it.Release() - for it.Next() { - bes := BlockEpochState{} - err := rlp.DecodeBytes(it.Value(), &bes) - if err != nil { - s.Log.Crit("Failed to decode BlockEpochState", "err", err) - } - if !fn(*bes.BlockState, *bes.EpochState) { - break - } - } -} - -func (s *Store) GetHistoryEpochState(epoch idx.Epoch) *iblockproc.EpochState { - // check current BlockEpochState as a cache - if v := s.cache.BlockEpochState.Load(); v != nil { - bes := v.(*BlockEpochState) - if bes.EpochState.Epoch == epoch { - es := bes.EpochState.Copy() - return &es - } - } - _, es := s.GetHistoryBlockEpochState(epoch) - return es -} - -func (s *Store) HasHistoryBlockEpochState(epoch idx.Epoch) bool { - has, _ := s.table.BlockEpochStateHistory.Has(epoch.Bytes()) - return has -} - -func (s *Store) HasBlockEpochState() bool { - has, _ := s.table.BlockEpochState.Has([]byte(sKey)) - return has -} - -// SetBlockEpochState stores the latest block and epoch state in memory -func (s *Store) SetBlockEpochState(bs iblockproc.BlockState, es iblockproc.EpochState) { - bs, es = bs.Copy(), es.Copy() - s.cache.BlockEpochState.Store(&BlockEpochState{&bs, &es}) -} - -func (s *Store) getBlockEpochState() BlockEpochState { - if v := s.cache.BlockEpochState.Load(); v != nil { - return *v.(*BlockEpochState) - } - v, ok := s.rlp.Get(s.table.BlockEpochState, []byte(sKey), &BlockEpochState{}).(*BlockEpochState) - if !ok { - log.Crit("Epoch state reading failed: genesis not applied") - } - s.cache.BlockEpochState.Store(v) - return *v -} - -// FlushBlockEpochState stores the latest epoch and block state in DB -func (s *Store) FlushBlockEpochState() { - s.rlp.Set(s.table.BlockEpochState, []byte(sKey), s.getBlockEpochState()) -} - -// GetBlockState retrieves the latest block state -func (s *Store) GetBlockState() iblockproc.BlockState { - return *s.getBlockEpochState().BlockState -} - -// GetEpochState retrieves the latest epoch state -func (s *Store) GetEpochState() iblockproc.EpochState { - return *s.getBlockEpochState().EpochState -} - -func (s *Store) GetBlockEpochState() (iblockproc.BlockState, iblockproc.EpochState) { - bes := s.getBlockEpochState() - return *bes.BlockState, *bes.EpochState -} - -// GetEpoch retrieves the current epoch -func (s *Store) GetEpoch() idx.Epoch { - return s.GetEpochState().Epoch -} - -// GetValidators retrieves current validators -func (s *Store) GetValidators() *pos.Validators { - return s.GetEpochState().Validators -} - -// GetEpochValidators retrieves the current epoch and validators atomically -func (s *Store) GetEpochValidators() (*pos.Validators, idx.Epoch) { - es := s.GetEpochState() - return es.Validators, es.Epoch -} - -// GetLatestBlockIndex retrieves the current block number -func (s *Store) GetLatestBlockIndex() idx.Block { - return s.GetBlockState().LastBlock.Idx -} - -// GetRules retrieves current network rules -func (s *Store) GetRules() opera.Rules { - return s.GetEpochState().Rules -} - -// GetEvmChainConfig retrieves current EVM chain config -func (s *Store) GetEvmChainConfig() *ethparams.ChainConfig { - return s.GetRules().EvmChainConfig(s.GetUpgradeHeights()) -} - -// GetEpochRules retrieves current network rules and epoch atomically -func (s *Store) GetEpochRules() (opera.Rules, idx.Epoch) { - es := s.GetEpochState() - return es.Rules, es.Epoch -} diff --git a/evm/go-x1/gossip/store_epoch.go b/evm/go-x1/gossip/store_epoch.go deleted file mode 100644 index d11809b..0000000 --- a/evm/go-x1/gossip/store_epoch.go +++ /dev/null @@ -1,117 +0,0 @@ -package gossip - -/* - In LRU cache data stored like pointer -*/ - -import ( - "errors" - "fmt" - "sync/atomic" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/skiperrors" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" - - "github.com/Fantom-foundation/go-opera/logger" -) - -var ( - errDBClosed = errors.New("database closed") -) - -type ( - epochStore struct { - epoch idx.Epoch - db kvdb.Store - table struct { - LastEvents kvdb.Store `table:"t"` - Heads kvdb.Store `table:"H"` - DagIndex kvdb.Store `table:"v"` - } - cache struct { - Heads atomic.Value - LastEvents atomic.Value - } - - logger.Instance - } -) - -func newEpochStore(epoch idx.Epoch, db kvdb.Store) *epochStore { - es := &epochStore{ - epoch: epoch, - db: db, - Instance: logger.New("epoch-store"), - } - table.MigrateTables(&es.table, db) - - // wrap with skiperrors to skip errors on reading from a dropped DB - es.table.LastEvents = skiperrors.Wrap(es.table.LastEvents, errDBClosed) - es.table.Heads = skiperrors.Wrap(es.table.Heads, errDBClosed) - - // load the cache to avoid a race condition - es.GetHeads() - es.GetLastEvents() - - return es -} - -func (s *Store) getAnyEpochStore() *epochStore { - _es := s.epochStore.Load() - if _es == nil { - return nil - } - return _es.(*epochStore) -} - -// getEpochStore is safe for concurrent use. -func (s *Store) getEpochStore(epoch idx.Epoch) *epochStore { - es := s.getAnyEpochStore() - if es.epoch != epoch { - return nil - } - return es -} - -func (s *Store) resetEpochStore(newEpoch idx.Epoch) { - oldEs := s.epochStore.Load() - // create new DB - s.createEpochStore(newEpoch) - // drop previous DB - // there may be race condition with threads which hold this DB, so wrap tables with skiperrors - if oldEs != nil { - err := oldEs.(*epochStore).db.Close() - if err != nil { - s.Log.Error("Failed to close epoch DB", "err", err) - return - } - oldEs.(*epochStore).db.Drop() - } -} - -func (s *Store) loadEpochStore(epoch idx.Epoch) { - if s.epochStore.Load() != nil { - return - } - s.createEpochStore(epoch) -} - -func (s *Store) closeEpochStore() error { - es := s.getAnyEpochStore() - if es == nil { - return nil - } - return es.db.Close() -} - -func (s *Store) createEpochStore(epoch idx.Epoch) { - // create new DB - name := fmt.Sprintf("gossip-%d", epoch) - db, err := s.dbs.OpenDB(name) - if err != nil { - s.Log.Crit("Filed to open DB", "name", name, "err", err) - } - s.epochStore.Store(newEpochStore(epoch, db)) -} diff --git a/evm/go-x1/gossip/store_event.go b/evm/go-x1/gossip/store_event.go deleted file mode 100644 index eba9813..0000000 --- a/evm/go-x1/gossip/store_event.go +++ /dev/null @@ -1,206 +0,0 @@ -package gossip - -/* - In LRU cache data stored like pointer -*/ - -import ( - "bytes" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/inter" -) - -// DelEvent deletes event. -func (s *Store) DelEvent(id hash.Event) { - key := id.Bytes() - - err := s.table.Events.Delete(key) - if err != nil { - s.Log.Crit("Failed to delete key", "err", err) - } - - // Remove from LRU cache. - s.cache.Events.Remove(id) - s.cache.EventsHeaders.Remove(id) - s.cache.EventIDs.Remove(id) -} - -// SetEvent stores event. -func (s *Store) SetEvent(e *inter.EventPayload) { - key := e.ID().Bytes() - - s.rlp.Set(s.table.Events, key, e) - - // Add to LRU cache. - s.cache.Events.Add(e.ID(), e, uint(e.Size())) - eh := e.Event - s.cache.EventsHeaders.Add(e.ID(), &eh, nominalSize) - s.cache.EventIDs.Add(e.ID()) -} - -// GetEventPayload returns stored event. -func (s *Store) GetEventPayload(id hash.Event) *inter.EventPayload { - // Get event from LRU cache first. - if ev, ok := s.cache.Events.Get(id); ok { - return ev.(*inter.EventPayload) - } - - key := id.Bytes() - w, _ := s.rlp.Get(s.table.Events, key, &inter.EventPayload{}).(*inter.EventPayload) - - if w != nil { - fixEventTxHashes(w) - } - - // Put event to LRU cache. - if w != nil { - s.cache.Events.Add(id, w, uint(w.Size())) - eh := w.Event - s.cache.EventsHeaders.Add(id, &eh, nominalSize) - } - - return w -} - -// GetEvent returns stored event. -func (s *Store) GetEvent(id hash.Event) *inter.Event { - // Get event from LRU cache first. - if ev, ok := s.cache.EventsHeaders.Get(id); ok { - return ev.(*inter.Event) - } - - key := id.Bytes() - w, _ := s.rlp.Get(s.table.Events, key, &inter.EventPayload{}).(*inter.EventPayload) - if w == nil { - return nil - } - fixEventTxHashes(w) - - eh := w.Event - - // Put event to LRU cache. - s.cache.Events.Add(id, w, uint(w.Size())) - s.cache.EventsHeaders.Add(id, &eh, nominalSize) - - return &eh -} - -func (s *Store) forEachEvent(it ethdb.Iterator, onEvent func(event *inter.EventPayload) bool) { - for it.Next() { - event := &inter.EventPayload{} - err := rlp.DecodeBytes(it.Value(), event) - if err != nil { - s.Log.Crit("Failed to decode event", "err", err) - } - - if !onEvent(event) { - return - } - } -} - -func (s *Store) ForEachEpochEvent(epoch idx.Epoch, onEvent func(event *inter.EventPayload) bool) { - it := s.table.Events.NewIterator(epoch.Bytes(), nil) - defer it.Release() - s.forEachEvent(it, onEvent) -} - -func (s *Store) ForEachEvent(start idx.Epoch, onEvent func(event *inter.EventPayload) bool) { - it := s.table.Events.NewIterator(nil, start.Bytes()) - defer it.Release() - s.forEachEvent(it, onEvent) -} - -func (s *Store) ForEachEventRLP(start []byte, onEvent func(key hash.Event, event rlp.RawValue) bool) { - it := s.table.Events.NewIterator(nil, start) - defer it.Release() - for it.Next() { - if !onEvent(hash.BytesToEvent(it.Key()), it.Value()) { - return - } - } -} - -func (s *Store) FindEventHashes(epoch idx.Epoch, lamport idx.Lamport, hashPrefix []byte) hash.Events { - prefix := bytes.NewBuffer(epoch.Bytes()) - prefix.Write(lamport.Bytes()) - prefix.Write(hashPrefix) - res := make(hash.Events, 0, 10) - - it := s.table.Events.NewIterator(prefix.Bytes(), nil) - defer it.Release() - for it.Next() { - res = append(res, hash.BytesToEvent(it.Key())) - } - - return res -} - -// GetEventPayloadRLP returns stored event. Serialized. -func (s *Store) GetEventPayloadRLP(id hash.Event) rlp.RawValue { - key := id.Bytes() - - data, err := s.table.Events.Get(key) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - return data -} - -// HasEvent returns true if event exists. -func (s *Store) HasEvent(h hash.Event) bool { - if has, ok := s.cache.EventIDs.Has(h); ok { - return has - } - has, _ := s.table.Events.Has(h.Bytes()) - return has -} - -func (s *Store) loadHighestLamport() idx.Lamport { - lamportBytes, err := s.table.HighestLamport.Get([]byte("k")) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if lamportBytes == nil { - return 0 - } - return idx.BytesToLamport(lamportBytes) -} - -func (s *Store) getCachedHighestLamport() (idx.Lamport, bool) { - cache := s.cache.HighestLamport.Load() - if cache != nil { - return cache.(idx.Lamport), true - } - return 0, false -} - -func (s *Store) GetHighestLamport() idx.Lamport { - cached, ok := s.getCachedHighestLamport() - if ok { - return cached - } - lamport := s.loadHighestLamport() - s.cache.HighestLamport.Store(lamport) - return lamport -} - -func (s *Store) SetHighestLamport(lamport idx.Lamport) { - s.cache.HighestLamport.Store(lamport) -} - -func (s *Store) FlushHighestLamport() { - cached, ok := s.getCachedHighestLamport() - if !ok { - return - } - err := s.table.HighestLamport.Put([]byte("k"), cached.Bytes()) - if err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } -} diff --git a/evm/go-x1/gossip/store_heads.go b/evm/go-x1/gossip/store_heads.go deleted file mode 100644 index 36ed821..0000000 --- a/evm/go-x1/gossip/store_heads.go +++ /dev/null @@ -1,108 +0,0 @@ -package gossip - -import ( - "bytes" - "sort" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/utils/concurrent" -) - -type sortedHead []byte - -func (es *epochStore) getCachedHeads() (*concurrent.EventsSet, bool) { - cache := es.cache.Heads.Load() - if cache != nil { - return cache.(*concurrent.EventsSet), true - } - return nil, false -} - -func (es *epochStore) loadHeads() *concurrent.EventsSet { - res := make(hash.EventsSet, 100) - - b, err := es.table.Heads.Get([]byte{}) - if err != nil { - es.Log.Crit("Failed to get key-value", "err", err) - } - if b == nil { - return concurrent.WrapEventsSet(res) - } - for i := 0; i < len(b); i += 32 { - res.Add(hash.BytesToEvent(b[i : i+32])) - } - - return concurrent.WrapEventsSet(res) -} - -func (es *epochStore) GetHeads() *concurrent.EventsSet { - cached, ok := es.getCachedHeads() - if ok { - return cached - } - heads := es.loadHeads() - if heads == nil { - heads = &concurrent.EventsSet{} - } - es.cache.Heads.Store(heads) - return heads -} - -func (es *epochStore) SetHeads(ids *concurrent.EventsSet) { - es.cache.Heads.Store(ids) -} - -func (es *epochStore) FlushHeads() { - ids, ok := es.getCachedHeads() - if !ok { - return - } - - // sort values for determinism - sortedHeads := make([]sortedHead, 0, len(ids.Val)) - for id := range ids.Val { - sortedHeads = append(sortedHeads, id.Bytes()) - } - sort.Slice(sortedHeads, func(i, j int) bool { - a, b := sortedHeads[i], sortedHeads[j] - return bytes.Compare(a, b) < 0 - }) - - b := make([]byte, 0, len(sortedHeads)*32) - for _, head := range sortedHeads { - b = append(b, head...) - } - - if err := es.table.Heads.Put([]byte{}, b); err != nil { - es.Log.Crit("Failed to put key-value", "err", err) - } -} - -// GetHeadsSlice returns IDs of all the epoch events with no descendants -func (s *Store) GetHeadsSlice(epoch idx.Epoch) hash.Events { - heads := s.GetHeads(epoch) - heads.RLock() - defer heads.RUnlock() - return heads.Val.Slice() -} - -// GetHeads returns set of all the epoch event IDs with no descendants -func (s *Store) GetHeads(epoch idx.Epoch) *concurrent.EventsSet { - es := s.getEpochStore(epoch) - if es == nil { - return nil - } - - return es.GetHeads() -} - -func (s *Store) SetHeads(epoch idx.Epoch, ids *concurrent.EventsSet) { - es := s.getEpochStore(epoch) - if es == nil { - return - } - - es.SetHeads(ids) -} diff --git a/evm/go-x1/gossip/store_last_bv.go b/evm/go-x1/gossip/store_last_bv.go deleted file mode 100644 index a947c88..0000000 --- a/evm/go-x1/gossip/store_last_bv.go +++ /dev/null @@ -1,93 +0,0 @@ -package gossip - -import ( - "bytes" - "sort" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/utils/concurrent" -) - -type sortedLastBV []byte - -func (s *Store) getCachedLastBVs() (*concurrent.ValidatorBlocksSet, bool) { - cache := s.cache.LastBVs.Load() - if cache != nil { - return cache.(*concurrent.ValidatorBlocksSet), true - } - return nil, false -} - -func (s *Store) loadLastBVs() *concurrent.ValidatorBlocksSet { - res := make(map[idx.ValidatorID]idx.Block, 100) - - b, err := s.table.LlrLastBlockVotes.Get([]byte{}) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if b == nil { - return concurrent.WrapValidatorBlocksSet(res) - } - for i := 0; i < len(b); i += 8 + 4 { - res[idx.BytesToValidatorID(b[i:i+4])] = idx.BytesToBlock(b[i+4 : i+4+8]) - } - - return concurrent.WrapValidatorBlocksSet(res) -} - -func (s *Store) GetLastBVs() *concurrent.ValidatorBlocksSet { - cached, ok := s.getCachedLastBVs() - if ok { - return cached - } - heads := s.loadLastBVs() - if heads == nil { - heads = &concurrent.ValidatorBlocksSet{} - } - s.cache.LastBVs.Store(heads) - return heads -} - -func (s *Store) SetLastBVs(ids *concurrent.ValidatorBlocksSet) { - s.cache.LastBVs.Store(ids) -} - -func (s *Store) FlushLastBVs() { - lasts, ok := s.getCachedLastBVs() - if !ok { - return - } - - // sort values for determinism - sortedLastBVs := make([]sortedLastBV, 0, len(lasts.Val)) - for vid, val := range lasts.Val { - b := append(vid.Bytes(), val.Bytes()...) - sortedLastBVs = append(sortedLastBVs, b) - } - sort.Slice(sortedLastBVs, func(i, j int) bool { - a, b := sortedLastBVs[i], sortedLastBVs[j] - return bytes.Compare(a, b) < 0 - }) - - b := make([]byte, 0, len(sortedLastBVs)*(8+4)) - for _, head := range sortedLastBVs { - b = append(b, head...) - } - - if err := s.table.LlrLastBlockVotes.Put([]byte{}, b); err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } -} - -// GetLastBV returns latest connected LLR block votes from specified validator -func (s *Store) GetLastBV(vid idx.ValidatorID) *idx.Block { - lasts := s.GetLastBVs() - lasts.RLock() - defer lasts.RUnlock() - last, ok := lasts.Val[vid] - if !ok { - return nil - } - return &last -} diff --git a/evm/go-x1/gossip/store_last_ev.go b/evm/go-x1/gossip/store_last_ev.go deleted file mode 100644 index 8a470be..0000000 --- a/evm/go-x1/gossip/store_last_ev.go +++ /dev/null @@ -1,93 +0,0 @@ -package gossip - -import ( - "bytes" - "sort" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/utils/concurrent" -) - -type sortedLastEV []byte - -func (s *Store) getCachedLastEV() (*concurrent.ValidatorEpochsSet, bool) { - cache := s.cache.LastEV.Load() - if cache != nil { - return cache.(*concurrent.ValidatorEpochsSet), true - } - return nil, false -} - -func (s *Store) loadLastEV() *concurrent.ValidatorEpochsSet { - res := make(map[idx.ValidatorID]idx.Epoch, 100) - - b, err := s.table.LlrLastEpochVote.Get([]byte{}) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if b == nil { - return concurrent.WrapValidatorEpochsSet(res) - } - for i := 0; i < len(b); i += 4 + 4 { - res[idx.BytesToValidatorID(b[i:i+4])] = idx.BytesToEpoch(b[i+4 : i+4+4]) - } - - return concurrent.WrapValidatorEpochsSet(res) -} - -func (s *Store) GetLastEVs() *concurrent.ValidatorEpochsSet { - cached, ok := s.getCachedLastEV() - if ok { - return cached - } - heads := s.loadLastEV() - if heads == nil { - heads = &concurrent.ValidatorEpochsSet{} - } - s.cache.LastEV.Store(heads) - return heads -} - -func (s *Store) SetLastEVs(ids *concurrent.ValidatorEpochsSet) { - s.cache.LastEV.Store(ids) -} - -func (s *Store) FlushLastEV() { - lasts, ok := s.getCachedLastEV() - if !ok { - return - } - - // sort values for determinism - sortedLastEV := make([]sortedLastEV, 0, len(lasts.Val)) - for vid, val := range lasts.Val { - b := append(vid.Bytes(), val.Bytes()...) - sortedLastEV = append(sortedLastEV, b) - } - sort.Slice(sortedLastEV, func(i, j int) bool { - a, b := sortedLastEV[i], sortedLastEV[j] - return bytes.Compare(a, b) < 0 - }) - - b := make([]byte, 0, len(sortedLastEV)*(4+4)) - for _, head := range sortedLastEV { - b = append(b, head...) - } - - if err := s.table.LlrLastEpochVote.Put([]byte{}, b); err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } -} - -// GetLastEV returns latest connected LLR epoch vote from specified validator -func (s *Store) GetLastEV(vid idx.ValidatorID) *idx.Epoch { - lasts := s.GetLastEVs() - lasts.RLock() - defer lasts.RUnlock() - last, ok := lasts.Val[vid] - if !ok { - return nil - } - return &last -} diff --git a/evm/go-x1/gossip/store_last_events.go b/evm/go-x1/gossip/store_last_events.go deleted file mode 100644 index 11f4bc9..0000000 --- a/evm/go-x1/gossip/store_last_events.go +++ /dev/null @@ -1,118 +0,0 @@ -package gossip - -import ( - "bytes" - "sort" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/utils/concurrent" -) - -type sortedLastEvent []byte - -func (es *epochStore) getCachedLastEvents() (*concurrent.ValidatorEventsSet, bool) { - cache := es.cache.LastEvents.Load() - if cache != nil { - return cache.(*concurrent.ValidatorEventsSet), true - } - return nil, false -} - -func (es *epochStore) loadLastEvents() *concurrent.ValidatorEventsSet { - res := make(map[idx.ValidatorID]hash.Event, 100) - - b, err := es.table.LastEvents.Get([]byte{}) - if err != nil { - es.Log.Crit("Failed to get key-value", "err", err) - } - if b == nil { - return concurrent.WrapValidatorEventsSet(res) - } - for i := 0; i < len(b); i += 32 + 4 { - res[idx.BytesToValidatorID(b[i:i+4])] = hash.BytesToEvent(b[i+4 : i+4+32]) - } - - return concurrent.WrapValidatorEventsSet(res) -} - -func (es *epochStore) GetLastEvents() *concurrent.ValidatorEventsSet { - cached, ok := es.getCachedLastEvents() - if ok { - return cached - } - heads := es.loadLastEvents() - if heads == nil { - heads = &concurrent.ValidatorEventsSet{} - } - es.cache.LastEvents.Store(heads) - return heads -} - -func (es *epochStore) SetLastEvents(ids *concurrent.ValidatorEventsSet) { - es.cache.LastEvents.Store(ids) -} - -func (es *epochStore) FlushLastEvents() { - lasts, ok := es.getCachedLastEvents() - if !ok { - return - } - - // sort values for determinism - sortedLastEvents := make([]sortedLastEvent, 0, len(lasts.Val)) - for vid, val := range lasts.Val { - b := append(vid.Bytes(), val.Bytes()...) - sortedLastEvents = append(sortedLastEvents, b) - } - sort.Slice(sortedLastEvents, func(i, j int) bool { - a, b := sortedLastEvents[i], sortedLastEvents[j] - return bytes.Compare(a, b) < 0 - }) - - b := make([]byte, 0, len(sortedLastEvents)*(32+4)) - for _, head := range sortedLastEvents { - b = append(b, head...) - } - - if err := es.table.LastEvents.Put([]byte{}, b); err != nil { - es.Log.Crit("Failed to put key-value", "err", err) - } -} - -// GetLastEvents returns latest connected epoch events from each validator -func (s *Store) GetLastEvents(epoch idx.Epoch) *concurrent.ValidatorEventsSet { - es := s.getEpochStore(epoch) - if es == nil { - return nil - } - - return es.GetLastEvents() -} - -// GetLastEvent returns latest connected epoch event from specified validator -func (s *Store) GetLastEvent(epoch idx.Epoch, vid idx.ValidatorID) *hash.Event { - es := s.getEpochStore(epoch) - if es == nil { - return nil - } - - lasts := s.GetLastEvents(epoch) - lasts.RLock() - defer lasts.RUnlock() - last, ok := lasts.Val[vid] - if !ok { - return nil - } - return &last -} - -func (s *Store) SetLastEvents(epoch idx.Epoch, ids *concurrent.ValidatorEventsSet) { - es := s.getEpochStore(epoch) - if es == nil { - return - } - - es.SetLastEvents(ids) -} diff --git a/evm/go-x1/gossip/store_llr_block.go b/evm/go-x1/gossip/store_llr_block.go deleted file mode 100644 index 79f48ee..0000000 --- a/evm/go-x1/gossip/store_llr_block.go +++ /dev/null @@ -1,270 +0,0 @@ -package gossip - -import ( - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/utils/simplewlru" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/utils/bitmap" -) - -func (s *Store) SetBlockVotes(bvs inter.LlrSignedBlockVotes) { - s.rlp.Set(s.table.LlrBlockVotes, append(bvs.Val.Epoch.Bytes(), append(bvs.Val.LastBlock().Bytes(), bvs.Signed.Locator.ID().Bytes()...)...), &bvs) -} - -func (s *Store) HasBlockVotes(epoch idx.Epoch, lastBlock idx.Block, id hash.Event) bool { - ok, _ := s.table.LlrBlockVotes.Has(append(epoch.Bytes(), append(lastBlock.Bytes(), id.Bytes()...)...)) - return ok -} - -func (s *Store) IterateOverlappingBlockVotesRLP(start []byte, f func(key []byte, bvs rlp.RawValue) bool) { - it := s.table.LlrBlockVotes.NewIterator(nil, start) - defer it.Release() - for it.Next() { - if !f(it.Key(), it.Value()) { - break - } - } -} - -func (s *Store) getLlrVoteWeight(cache *VotesCache, reader kvdb.Reader, cKey VotesCacheID, key []byte) (pos.Weight, bitmap.Set) { - if cached := cache.Get(cKey); cached != nil { - return cached.weight, cached.set - } - weightB, err := reader.Get(key) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if weightB == nil { - return 0, nil - } - weight, set := pos.Weight(bigendian.BytesToUint32(weightB[:4])), weightB[4:] - cache.Add(cKey, VotesCacheValue{ - weight: weight, - set: set, - mutated: false, - }) - return weight, set -} - -func (s *Store) flushLlrVoteWeight(table kvdb.Writer, key []byte, weight pos.Weight, set bitmap.Set) { - err := table.Put(key, append(bigendian.Uint32ToBytes(uint32(weight)), set...)) - if err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } -} - -func (s *Store) flushLlrBlockVoteWeight(cKey VotesCacheID, value VotesCacheValue) { - key := append(cKey.Block.Bytes(), append(cKey.Epoch.Bytes(), cKey.V[:]...)...) - s.flushLlrVoteWeight(s.table.LlrBlockVotesIndex, key, value.weight, value.set) -} - -func (s *Store) addLlrVoteWeight(cache *VotesCache, reader kvdb.Reader, cKey VotesCacheID, key []byte, validator idx.Validator, validatorsNum idx.Validator, diff pos.Weight) pos.Weight { - weight, set := s.getLlrVoteWeight(cache, reader, cKey, key) - if set != nil && set.Has(int(validator)) { - // don't count the vote if validator already voted - return weight - } - if set == nil { - set = bitmap.New(int(validatorsNum)) - } - set.Put(int(validator)) - weight += diff - // save to cache which will be later flushed to the DB - cache.Add(cKey, VotesCacheValue{ - weight: weight, - set: set, - mutated: true, - }) - return weight -} - -func (s *Store) AddLlrBlockVoteWeight(block idx.Block, epoch idx.Epoch, bv hash.Hash, val idx.Validator, vals idx.Validator, diff pos.Weight) pos.Weight { - key := append(block.Bytes(), append(epoch.Bytes(), bv[:]...)...) - cKey := VotesCacheID{ - Block: block, - Epoch: epoch, - V: bv, - } - return s.addLlrVoteWeight(s.cache.LlrBlockVotesIndex, s.table.LlrBlockVotesIndex, cKey, key, val, vals, diff) -} - -func (s *Store) SetLlrBlockResult(block idx.Block, bv hash.Hash) { - err := s.table.LlrBlockResults.Put(block.Bytes(), bv.Bytes()) - if err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } -} - -func (s *Store) GetLlrBlockResult(block idx.Block) *hash.Hash { - bvB, err := s.table.LlrBlockResults.Get(block.Bytes()) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if bvB == nil { - return nil - } - bv := hash.BytesToHash(bvB) - return &bv -} - -func (s *Store) GetFullBlockRecord(n idx.Block) *ibr.LlrFullBlockRecord { - block := s.GetBlock(n) - if block == nil { - return nil - } - txs := s.GetBlockTxs(n, block) - receipts, _ := s.EvmStore().GetRawReceipts(n) - if receipts == nil { - receipts = []*types.ReceiptForStorage{} - } - return &ibr.LlrFullBlockRecord{ - Atropos: block.Atropos, - Root: block.Root, - Txs: txs, - Receipts: receipts, - Time: block.Time, - GasUsed: block.GasUsed, - } -} - -func (s *Store) GetBlockRecordHash(n idx.Block) *hash.Hash { - // Get data from LRU cache first. - if s.cache.BRHashes != nil { - if c, ok := s.cache.BRHashes.Get(n); ok { - h := c.(hash.Hash) - return &h - } - } - br := s.GetFullBlockRecord(n) - if br == nil { - return nil - } - brHash := br.Hash() - // Add to LRU cache. - s.cache.BRHashes.Add(n, brHash, nominalSize) - return &brHash -} - -func (s *Store) GetFullEpochRecord(epoch idx.Epoch) *ier.LlrFullEpochRecord { - hbs, hes := s.GetHistoryBlockEpochState(epoch) - if hbs == nil || hes == nil { - return nil - } - return &ier.LlrFullEpochRecord{ - BlockState: *hbs, - EpochState: *hes, - } -} - -type LlrFullBlockRecordRLP struct { - Atropos hash.Event - Root hash.Hash - Txs types.Transactions - ReceiptsRLP rlp.RawValue - Time inter.Timestamp - GasUsed uint64 -} - -type LlrIdxFullBlockRecordRLP struct { - LlrFullBlockRecordRLP - Idx idx.Block -} - -var emptyReceiptsRLP, _ = rlp.EncodeToBytes([]*types.ReceiptForStorage{}) - -func (s *Store) IterateFullBlockRecordsRLP(start idx.Block, f func(b idx.Block, br rlp.RawValue) bool) { - it := s.table.Blocks.NewIterator(nil, start.Bytes()) - defer it.Release() - for it.Next() { - block := &inter.Block{} - err := rlp.DecodeBytes(it.Value(), block) - if err != nil { - s.Log.Crit("Failed to decode block", "err", err) - } - n := idx.BytesToBlock(it.Key()) - txs := s.GetBlockTxs(n, block) - receiptsRLP := s.EvmStore().GetRawReceiptsRLP(n) - if receiptsRLP == nil { - receiptsRLP = emptyReceiptsRLP - } - br := LlrIdxFullBlockRecordRLP{ - LlrFullBlockRecordRLP: LlrFullBlockRecordRLP{ - Atropos: block.Atropos, - Root: block.Root, - Txs: txs, - ReceiptsRLP: receiptsRLP, - Time: block.Time, - GasUsed: block.GasUsed, - }, - Idx: n, - } - encoded, err := rlp.EncodeToBytes(br) - if err != nil { - s.Log.Crit("Failed to encode BR", "err", err) - } - - if !f(n, encoded) { - break - } - } -} - -type VotesCacheID struct { - Block idx.Block - Epoch idx.Epoch - V hash.Hash -} - -type VotesCacheValue struct { - weight pos.Weight - set bitmap.Set - mutated bool -} - -type VotesCache struct { - votes *simplewlru.Cache -} - -func NewVotesCache(maxSize int, evictedFn func(VotesCacheID, VotesCacheValue)) *VotesCache { - votes, _ := simplewlru.NewWithEvict(uint(maxSize), maxSize, func(key interface{}, _value interface{}) { - value := _value.(*VotesCacheValue) - if value.mutated { - evictedFn(key.(VotesCacheID), *value) - } - }) - return &VotesCache{ - votes: votes, - } -} - -func (c *VotesCache) FlushMutated(write func(VotesCacheID, VotesCacheValue)) { - keys := c.votes.Keys() - for _, k := range keys { - val_, _ := c.votes.Peek(k) - val := val_.(*VotesCacheValue) - if val.mutated { - write(k.(VotesCacheID), *val) - val.mutated = false - } - } -} - -func (c *VotesCache) Get(key VotesCacheID) *VotesCacheValue { - if v, ok := c.votes.Get(key); ok { - return v.(*VotesCacheValue) - } - return nil -} - -func (c *VotesCache) Add(key VotesCacheID, val VotesCacheValue) { - c.votes.Add(key, &val, nominalSize) -} diff --git a/evm/go-x1/gossip/store_llr_epoch.go b/evm/go-x1/gossip/store_llr_epoch.go deleted file mode 100644 index 4736450..0000000 --- a/evm/go-x1/gossip/store_llr_epoch.go +++ /dev/null @@ -1,113 +0,0 @@ -package gossip - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/inter" -) - -const ( - maxEpochPackVotes = 10000 -) - -func (s *Store) SetEpochVote(ev inter.LlrSignedEpochVote) { - s.rlp.Set(s.table.LlrEpochVotes, append(ev.Val.Epoch.Bytes(), ev.Signed.Locator.ID().Bytes()...), &ev) -} - -func (s *Store) HasEpochVote(epoch idx.Epoch, id hash.Event) bool { - ok, _ := s.table.LlrEpochVotes.Has(append(epoch.Bytes(), id.Bytes()...)) - return ok -} - -func (s *Store) iterateEpochVotesRLP(prefix []byte, f func(ev rlp.RawValue) bool) { - it := s.table.LlrEpochVotes.NewIterator(prefix, nil) - defer it.Release() - for it.Next() { - if !f(common.CopyBytes(it.Value())) { - break - } - } -} - -func (s *Store) flushLlrEpochVoteWeight(cKey VotesCacheID, value VotesCacheValue) { - key := append(cKey.Epoch.Bytes(), cKey.V[:]...) - s.flushLlrVoteWeight(s.table.LlrEpochVoteIndex, key, value.weight, value.set) -} - -func (s *Store) AddLlrEpochVoteWeight(epoch idx.Epoch, ev hash.Hash, val idx.Validator, vals idx.Validator, diff pos.Weight) pos.Weight { - key := append(epoch.Bytes(), ev[:]...) - cKey := VotesCacheID{ - Block: 0, - Epoch: epoch, - V: ev, - } - return s.addLlrVoteWeight(s.cache.LlrEpochVoteIndex, s.table.LlrEpochVoteIndex, cKey, key, val, vals, diff) -} - -func (s *Store) SetLlrEpochResult(epoch idx.Epoch, ev hash.Hash) { - err := s.table.LlrEpochResults.Put(epoch.Bytes(), ev.Bytes()) - if err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } -} - -func (s *Store) GetLlrEpochResult(epoch idx.Epoch) *hash.Hash { - evB, err := s.table.LlrEpochResults.Get(epoch.Bytes()) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if evB == nil { - return nil - } - ev := hash.BytesToHash(evB) - return &ev -} - -type LlrIdxFullEpochRecordRLP struct { - RecordRLP rlp.RawValue - Idx idx.Epoch -} - -type LlrEpochPackRLP struct { - VotesRLP []rlp.RawValue - Record LlrIdxFullEpochRecordRLP -} - -func (s *Store) IterateEpochPacksRLP(start idx.Epoch, f func(epoch idx.Epoch, ep rlp.RawValue) bool) { - for epoch := start; ; epoch++ { - key := epoch.Bytes() - val, err := s.table.BlockEpochStateHistory.Get(key) - if err != nil { - s.Log.Crit("Failed to get block-epoch state", "err", err) - } - if val == nil { - break - } - evs := make([]rlp.RawValue, 0, 20) - s.iterateEpochVotesRLP(key, func(ev rlp.RawValue) bool { - evs = append(evs, ev) - return len(evs) < maxEpochPackVotes - }) - if len(evs) == 0 { - continue - } - ep := &LlrEpochPackRLP{ - VotesRLP: evs, - Record: LlrIdxFullEpochRecordRLP{ - RecordRLP: val, - Idx: epoch, - }, - } - encoded, err := rlp.EncodeToBytes(ep) - if err != nil { - s.Log.Crit("Failed to encode BR", "err", err) - } - if !f(epoch, encoded) { - break - } - } -} diff --git a/evm/go-x1/gossip/store_llr_state.go b/evm/go-x1/gossip/store_llr_state.go deleted file mode 100644 index 0bd6816..0000000 --- a/evm/go-x1/gossip/store_llr_state.go +++ /dev/null @@ -1,43 +0,0 @@ -package gossip - -import ( - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/log" -) - -type LlrState struct { - LowestEpochToDecide idx.Epoch - LowestEpochToFill idx.Epoch - - LowestBlockToDecide idx.Block - LowestBlockToFill idx.Block -} - -func (s *Store) setLlrState(llrs LlrState) { - s.cache.LlrState.Store(&llrs) -} - -func (s *Store) ModifyLlrState(f func(*LlrState)) { - s.mutex.WriteLlrState.Lock() - defer s.mutex.WriteLlrState.Unlock() - llrs := s.GetLlrState() - f(&llrs) - s.setLlrState(llrs) -} - -func (s *Store) GetLlrState() LlrState { - if v := s.cache.LlrState.Load(); v != nil { - return *v.(*LlrState) - } - v, ok := s.rlp.Get(s.table.LlrState, []byte{}, &LlrState{}).(*LlrState) - if !ok { - log.Crit("LLR state reading failed: genesis not applied") - } - s.cache.LlrState.Store(v) - return *v -} - -// FlushLlrState stores the LLR state in DB -func (s *Store) FlushLlrState() { - s.rlp.Set(s.table.LlrState, []byte{}, s.GetLlrState()) -} diff --git a/evm/go-x1/gossip/store_migration.go b/evm/go-x1/gossip/store_migration.go deleted file mode 100644 index 5c46b0e..0000000 --- a/evm/go-x1/gossip/store_migration.go +++ /dev/null @@ -1,143 +0,0 @@ -package gossip - -import ( - "errors" - "fmt" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/common" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/utils/migration" -) - -func isEmptyDB(db kvdb.Iteratee) bool { - it := db.NewIterator(nil, nil) - defer it.Release() - return !it.Next() -} - -func (s *Store) migrateData() error { - versions := migration.NewKvdbIDStore(s.table.Version) - if isEmptyDB(s.table.Version) { - // short circuit if empty DB - versions.SetID(s.migrations().ID()) - return nil - } - - err := s.migrations().Exec(versions, s.flushDBs) - return err -} - -func (s *Store) migrations() *migration.Migration { - return migration. - Begin("opera-gossip-store"). - Next("used gas recovery", unsupportedMigration). - Next("tx hashes recovery", unsupportedMigration). - Next("DAG heads recovery", unsupportedMigration). - Next("DAG last events recovery", unsupportedMigration). - Next("BlockState recovery", unsupportedMigration). - Next("LlrState recovery", s.recoverLlrState). - Next("erase gossip-async db", s.eraseGossipAsyncDB). - Next("erase SFC API table", s.eraseSfcApiTable). - Next("erase legacy genesis DB", s.eraseGenesisDB). - Next("calculate upgrade heights", s.calculateUpgradeHeights) -} - -func unsupportedMigration() error { - return fmt.Errorf("DB version isn't supported, please restart from scratch") -} - -var ( - fixTxHash1 = common.HexToHash("0xb6840d4c0eb562b0b1731760223d91b36edc6c160958e23e773e6058eea30458") - fixTxEvent1 = hash.HexToEventHash("0x00001718000003d4d3955bf592e12fb80a60574fa4b18bd5805b4c010d75e86d") - fixTxHash2 = common.HexToHash("0x3aeede91740093cb8feb1296a34cf70d86d2f802cff860edd798978e94a40534") - fixTxEvent2 = hash.HexToEventHash("0x0000179e00000c464d756a7614d0ca067fcb37ee4452004bf308c9df561e85e8") -) - -const ( - fixTxEventPos1 = 2 - fixTxBlock1 = 4738821 - fixTxEventPos2 = 0 - fixTxBlock2 = 4801307 -) - -func fixEventTxHashes(e *inter.EventPayload) { - if e.ID() == fixTxEvent1 { - e.Txs()[fixTxEventPos1].SetHash(fixTxHash1) - } - if e.ID() == fixTxEvent2 { - e.Txs()[fixTxEventPos2].SetHash(fixTxHash2) - } -} - -func (s *Store) recoverLlrState() error { - v1, ok := s.rlp.Get(s.table.BlockEpochState, []byte(sKey), &BlockEpochState{}).(*BlockEpochState) - if !ok { - return errors.New("epoch state reading failed: genesis not applied") - } - - epoch := v1.EpochState.Epoch + 1 - block := v1.BlockState.LastBlock.Idx + 1 - - s.setLlrState(LlrState{ - LowestEpochToDecide: epoch, - LowestEpochToFill: epoch, - LowestBlockToDecide: block, - LowestBlockToFill: block, - }) - s.FlushLlrState() - return nil -} - -func (s *Store) eraseSfcApiTable() error { - sfcapiTable, _ := s.dbs.OpenDB("gossip/S") - it := sfcapiTable.NewIterator(nil, nil) - defer it.Release() - for it.Next() { - err := sfcapiTable.Delete(it.Key()) - if err != nil { - return err - } - } - return nil -} - -func (s *Store) eraseGossipAsyncDB() error { - asyncDB, err := s.dbs.OpenDB("gossip-async") - if err != nil { - return fmt.Errorf("failed to open gossip-async to drop: %v", err) - } - - _ = asyncDB.Close() - asyncDB.Drop() - - return nil -} - -func (s *Store) eraseGenesisDB() error { - genesisDB, err := s.dbs.OpenDB("genesis") - if err != nil { - return nil - } - - _ = genesisDB.Close() - genesisDB.Drop() - return nil -} - -func (s *Store) calculateUpgradeHeights() error { - var prevEs *iblockproc.EpochState - s.ForEachHistoryBlockEpochState(func(bs iblockproc.BlockState, es iblockproc.EpochState) bool { - s.WriteUpgradeHeight(bs, es, prevEs) - prevEs = &es - return true - }) - if prevEs == nil { - // special case when no history is available - s.WriteUpgradeHeight(s.GetBlockState(), s.GetEpochState(), nil) - } - return nil -} diff --git a/evm/go-x1/gossip/sync.go b/evm/go-x1/gossip/sync.go deleted file mode 100644 index 595136d..0000000 --- a/evm/go-x1/gossip/sync.go +++ /dev/null @@ -1,296 +0,0 @@ -package gossip - -import ( - "math/rand" - "sync/atomic" - "time" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/p2p/enode" -) - -type syncStage uint32 - -type syncStatus struct { - stage uint32 - maybeSynced uint32 -} - -const ( - ssUnknown syncStage = iota - ssSnaps - ssEvmSnapGen - ssEvents -) - -const ( - snapsyncMinEndAge = 14 * 24 * time.Hour - snapsyncMaxStartAge = 6 * time.Hour -) - -func (ss *syncStatus) Is(s ...syncStage) bool { - self := &ss.stage - for _, v := range s { - if atomic.LoadUint32(self) == uint32(v) { - return true - } - } - return false -} - -func (ss *syncStatus) Set(s syncStage) { - atomic.StoreUint32(&ss.stage, uint32(s)) -} - -func (ss *syncStatus) MaybeSynced() bool { - return atomic.LoadUint32(&ss.maybeSynced) != 0 -} - -func (ss *syncStatus) MarkMaybeSynced() { - atomic.StoreUint32(&ss.maybeSynced, uint32(1)) -} - -func (ss *syncStatus) AcceptEvents() bool { - return ss.Is(ssEvents) -} - -func (ss *syncStatus) AcceptBlockRecords() bool { - return !ss.Is(ssEvents) -} - -func (ss *syncStatus) AcceptTxs() bool { - return ss.MaybeSynced() && ss.Is(ssEvents) -} - -func (ss *syncStatus) RequestLLR() bool { - return !ss.Is(ssEvents) || ss.MaybeSynced() -} - -type txsync struct { - p *peer - txids []common.Hash -} - -// syncTransactions starts sending all currently pending transactions to the given peer. -func (h *handler) syncTransactions(p *peer, txids []common.Hash) { - if len(txids) == 0 { - return - } - select { - case h.txsyncCh <- &txsync{p, txids}: - case <-h.quitSync: - } -} - -// txsyncLoop takes care of the initial transaction sync for each new -// connection. When a new peer appears, we relay all currently pending -// transactions. In order to minimise egress bandwidth usage, we send -// the transactions in small packs to one peer at a time. -func (h *handler) txsyncLoop() { - var ( - pending = make(map[enode.ID]*txsync) - sending = false // whether a send is active - pack = new(txsync) // the pack that is being sent - done = make(chan error, 1) // result of the send - ) - - // send starts a sending a pack of transactions from the sync. - send := func(s *txsync) { - // Fill pack with transactions up to the target size. - pack.p = s.p - pack.txids = pack.txids[:0] - for i := 0; i < len(s.txids) && len(pack.txids) < softLimitItems; i++ { - pack.txids = append(pack.txids, s.txids[i]) - } - // Remove the transactions that will be sent. - s.txids = s.txids[len(pack.txids):] - if len(s.txids) == 0 { - delete(pending, s.p.ID()) - } - // Send the pack in the background. - s.p.Log().Trace("Sending batch of transaction hashes", "count", len(pack.txids)) - sending = true - go func() { - if len(pack.txids) != 0 { - done <- pack.p.SendTransactionHashes(pack.txids) - } else { - done <- nil - } - }() - } - - // pick chooses the next pending sync. - pick := func() *txsync { - if len(pending) == 0 { - return nil - } - n := rand.Intn(len(pending)) + 1 - for _, s := range pending { - if n--; n == 0 { - return s - } - } - return nil - } - - for { - select { - case s := <-h.txsyncCh: - pending[s.p.ID()] = s - if !sending { - send(s) - } - case err := <-done: - sending = false - // Stop tracking peers that cause send failures. - if err != nil { - pack.p.Log().Debug("Transaction send failed", "err", err) - delete(pending, pack.p.ID()) - } - // Schedule the next send. - if s := pick(); s != nil { - send(s) - } - case <-h.quitSync: - return - } - } -} - -func (h *handler) updateSnapsyncStage() { - // never allow fullsync while EVM snap is still generating, as it may lead to a race condition - snapGenOngoing, _ := h.store.evm.Snaps.Generating() - fullsyncPossibleEver := h.store.evm.HasStateDB(h.store.GetBlockState().FinalizedStateRoot) - fullsyncPossibleNow := fullsyncPossibleEver && !snapGenOngoing - // never allow to stop fullsync as it may lead to a race condition due to overwritten EVM snapshot by snapsync - snapsyncPossible := h.config.AllowSnapsync && (h.syncStatus.Is(ssUnknown) || h.syncStatus.Is(ssSnaps)) - snapsyncNeeded := !fullsyncPossibleEver || time.Since(h.store.GetEpochState().EpochStart.Time()) > snapsyncMinEndAge - - if snapsyncPossible && snapsyncNeeded { - h.syncStatus.Set(ssSnaps) - } else if snapGenOngoing { - h.syncStatus.Set(ssEvmSnapGen) - } else if fullsyncPossibleNow { - if !h.syncStatus.Is(ssEvents) { - h.Log.Info("Start/Switch to fullsync mode...") - } - h.syncStatus.Set(ssEvents) - } -} - -func (h *handler) snapsyncStageTick() { - // check if existing snapsync process can be resulted - h.updateSnapsyncStage() - llrs := h.store.GetLlrState() - if h.syncStatus.Is(ssSnaps) { - for i := 0; i < 3; i++ { - epoch := llrs.LowestEpochToFill - 1 - idx.Epoch(i) - if epoch <= h.store.GetEpoch() { - continue - } - bs, _ := h.store.GetHistoryBlockEpochState(epoch) - if bs == nil { - continue - } - if !h.store.evm.HasStateDB(bs.FinalizedStateRoot) { - continue - } - if llrs.LowestBlockToFill <= bs.LastBlock.Idx { - continue - } - if time.Since(bs.LastBlock.Time.Time()) > snapsyncMinEndAge { - continue - } - // cancel snapsync activity to prevent race condition - done := make(chan struct{}) - h.snapState.updatesCh <- snapsyncStateUpd{ - snapsyncCancelCmd: &snapsyncCancelCmd{done}, - } - <-done - // finalize snapsync - if err := h.process.SwitchEpochTo(epoch); err != nil { - h.Log.Error("Failed to result snapsync", "epoch", epoch, "block", bs.LastBlock.Idx, "err", err) - } else { - h.Log.Info("Snapsync is finalized at", "epoch", epoch, "block", bs.LastBlock.Idx, "root", bs.FinalizedStateRoot) - // switch state to non-snapsync and thus not allow ssSnaps ever again - h.syncStatus.Set(ssEvmSnapGen) - } - } - } - // push new data into an existing snapsync process - if h.syncStatus.Is(ssSnaps) { - lastEpoch := llrs.LowestEpochToFill - 1 - lastBs, _ := h.store.GetHistoryBlockEpochState(lastEpoch) - if lastBs != nil && time.Since(lastBs.LastBlock.Time.Time()) < snapsyncMaxStartAge { - h.snapState.updatesCh <- snapsyncStateUpd{ - snapsyncEpochUpd: &snapsyncEpochUpd{ - epoch: lastEpoch, - root: common.Hash(lastBs.FinalizedStateRoot), - }, - } - } - } - // resume events downloading if events sync is enabled - if h.syncStatus.Is(ssEvents) { - h.dagLeecher.Resume() - h.brLeecher.Pause() - } else { - h.dagLeecher.Pause() - h.brLeecher.Resume() - } -} - -func (h *handler) snapsyncStageLoop() { - ticker := time.NewTicker(200 * time.Millisecond) - defer ticker.Stop() - defer h.loopsWg.Done() - for { - select { - case <-ticker.C: - h.snapsyncStageTick() - case <-h.snapState.quit: - return - } - } -} - -// mayCancel cancels existing snapsync process if any -func (ss *snapsyncState) mayCancel() error { - if ss.cancel != nil { - err := ss.cancel() - ss.cancel = nil - return err - } - return nil -} - -func (h *handler) snapsyncStateLoop() { - defer h.loopsWg.Done() - for { - select { - case cmd := <-h.snapState.updatesCh: - if cmd.snapsyncEpochUpd != nil { - upd := cmd.snapsyncEpochUpd - // check if epoch has advanced - if h.snapState.epoch >= upd.epoch { - continue - } - h.snapState.epoch = upd.epoch - _ = h.snapState.mayCancel() - // start new snapsync state - h.Log.Info("Update snapsync epoch", "epoch", upd.epoch, "root", upd.root) - h.process.PauseEvmSnapshot() - ss := h.snapLeecher.SyncState(upd.root) - h.snapState.cancel = ss.Cancel - } - if cmd.snapsyncCancelCmd != nil { - _ = h.snapState.mayCancel() - cmd.snapsyncCancelCmd.done <- struct{}{} - } - case <-h.snapState.quit: - _ = h.snapState.mayCancel() - return - } - } -} diff --git a/evm/go-x1/gossip/tflusher.go b/evm/go-x1/gossip/tflusher.go deleted file mode 100644 index 488bf4b..0000000 --- a/evm/go-x1/gossip/tflusher.go +++ /dev/null @@ -1,47 +0,0 @@ -package gossip - -import ( - "sync" - "time" -) - -type PeriodicFlusherCallaback struct { - busy func() bool - commitNeeded func() bool - commit func() -} - -// PeriodicFlusher periodically commits the Store if isCommitNeeded returns true -type PeriodicFlusher struct { - period time.Duration - callback PeriodicFlusherCallaback - - wg sync.WaitGroup - quit chan struct{} -} - -func (c *PeriodicFlusher) loop() { - defer c.wg.Done() - ticker := time.NewTicker(c.period) - defer ticker.Stop() - for { - select { - case <-ticker.C: - if !c.callback.busy() && c.callback.commitNeeded() { - c.callback.commit() - } - case <-c.quit: - return - } - } -} - -func (c *PeriodicFlusher) Start() { - c.wg.Add(1) - go c.loop() -} - -func (c *PeriodicFlusher) Stop() { - close(c.quit) - c.wg.Wait() -} diff --git a/evm/go-x1/integration/assembly.go b/evm/go-x1/integration/assembly.go deleted file mode 100644 index 51b21d5..0000000 --- a/evm/go-x1/integration/assembly.go +++ /dev/null @@ -1,356 +0,0 @@ -package integration - -import ( - "crypto/ecdsa" - "errors" - "fmt" - "path" - - "github.com/Fantom-foundation/lachesis-base/abft" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/multidb" - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/status-im/keycard-go/hexutils" - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/utils/adapters/vecmt2dagidx" - "github.com/Fantom-foundation/go-opera/utils/dbutil/compactdb" - "github.com/Fantom-foundation/go-opera/vecmt" -) - -var ( - MetadataPrefix = hexutils.HexToBytes("0068c2927bf842c3e9e2f1364494a33a752db334b9a819534bc9f17d2c3b4e5970008ff519d35a86f29fcaa5aae706b75dee871f65f174fcea1747f2915fc92158f6bfbf5eb79f65d16225738594bffb") - FlushIDKey = append(common.CopyBytes(MetadataPrefix), 0x0c) - TablesKey = append(common.CopyBytes(MetadataPrefix), 0x0d) -) - -// GenesisMismatchError is raised when trying to overwrite an existing -// genesis block with an incompatible one. -type GenesisMismatchError struct { - Stored, New hash.Hash -} - -// Error implements error interface. -func (e *GenesisMismatchError) Error() string { - return fmt.Sprintf("database contains incompatible genesis (have %s, new %s)", e.Stored.String(), e.New.String()) -} - -type Configs struct { - Opera gossip.Config - OperaStore gossip.StoreConfig - Lachesis abft.Config - LachesisStore abft.StoreConfig - VectorClock vecmt.IndexConfig - DBs DBsConfig -} - -func panics(name string) func(error) { - return func(err error) { - log.Crit(fmt.Sprintf("%s error", name), "err", err) - } -} - -func mustOpenDB(producer kvdb.DBProducer, name string) kvdb.Store { - db, err := producer.OpenDB(name) - if err != nil { - utils.Fatalf("Failed to open '%s' database: %v", name, err) - } - return db -} - -func getStores(producer kvdb.FlushableDBProducer, cfg Configs) (*gossip.Store, *abft.Store) { - gdb := gossip.NewStore(producer, cfg.OperaStore) - - cMainDb := mustOpenDB(producer, "lachesis") - cGetEpochDB := func(epoch idx.Epoch) kvdb.Store { - return mustOpenDB(producer, fmt.Sprintf("lachesis-%d", epoch)) - } - cdb := abft.NewStore(cMainDb, cGetEpochDB, panics("Lachesis store"), cfg.LachesisStore) - return gdb, cdb -} - -func getEpoch(producer kvdb.FlushableDBProducer, cfg Configs) idx.Epoch { - gdb := gossip.NewStore(producer, cfg.OperaStore) - defer gdb.Close() - return gdb.GetEpoch() -} - -func rawApplyGenesis(gdb *gossip.Store, cdb *abft.Store, g genesis.Genesis, cfg Configs) error { - _, _, _, err := rawMakeEngine(gdb, cdb, &g, cfg) - return err -} - -func rawMakeEngine(gdb *gossip.Store, cdb *abft.Store, g *genesis.Genesis, cfg Configs) (*abft.Lachesis, *vecmt.Index, gossip.BlockProc, error) { - blockProc := gossip.DefaultBlockProc() - - if g != nil { - _, err := gdb.ApplyGenesis(*g) - if err != nil { - return nil, nil, blockProc, fmt.Errorf("failed to write Gossip genesis state: %v", err) - } - - err = cdb.ApplyGenesis(&abft.Genesis{ - Epoch: gdb.GetEpoch(), - Validators: gdb.GetValidators(), - }) - if err != nil { - return nil, nil, blockProc, fmt.Errorf("failed to write Lachesis genesis state: %v", err) - } - } - - // create consensus - vecClock := vecmt.NewIndex(panics("Vector clock"), cfg.VectorClock) - engine := abft.NewLachesis(cdb, &GossipStoreAdapter{gdb}, vecmt2dagidx.Wrap(vecClock), panics("Lachesis"), cfg.Lachesis) - return engine, vecClock, blockProc, nil -} - -func applyGenesis(dbs kvdb.FlushableDBProducer, g genesis.Genesis, cfg Configs) error { - gdb, cdb := getStores(dbs, cfg) - defer gdb.Close() - defer cdb.Close() - log.Info("Applying genesis state") - err := rawApplyGenesis(gdb, cdb, g, cfg) - if err != nil { - return err - } - err = gdb.Commit() - if err != nil { - return err - } - return nil -} - -func migrate(dbs kvdb.FlushableDBProducer, cfg Configs) error { - gdb, cdb := getStores(dbs, cfg) - defer gdb.Close() - defer cdb.Close() - err := gdb.Commit() - if err != nil { - return err - } - return nil -} - -func CheckStateInitialized(chaindataDir string, cfg DBsConfig) error { - if isInterrupted(chaindataDir) { - return errors.New("genesis processing isn't finished") - } - runtimeProducers, runtimeScopedProducers := SupportedDBs(chaindataDir, cfg.RuntimeCache) - dbs, err := MakeMultiProducer(runtimeProducers, runtimeScopedProducers, cfg.Routing) - if err != nil { - return err - } - return dbs.Close() -} - -func compactDB(typ multidb.TypeName, name string, producer kvdb.DBProducer) error { - humanName := path.Join(string(typ), name) - db, err := producer.OpenDB(name) - defer db.Close() - if err != nil { - return err - } - return compactdb.Compact(db, humanName, 16*opt.GiB) -} - -func makeEngine(chaindataDir string, g *genesis.Genesis, genesisProc bool, cfg Configs) (*abft.Lachesis, *vecmt.Index, *gossip.Store, *abft.Store, gossip.BlockProc, func() error, error) { - // Genesis processing - if genesisProc { - setGenesisProcessing(chaindataDir) - // use increased DB cache for genesis processing - genesisProducers, _ := SupportedDBs(chaindataDir, cfg.DBs.GenesisCache) - if g == nil { - return nil, nil, nil, nil, gossip.BlockProc{}, nil, fmt.Errorf("missing --genesis flag for an empty datadir") - } - dbs, err := MakeDirectMultiProducer(genesisProducers, cfg.DBs.Routing) - if err != nil { - return nil, nil, nil, nil, gossip.BlockProc{}, nil, fmt.Errorf("failed to make DB multi-producer: %v", err) - } - err = applyGenesis(dbs, *g, cfg) - if err != nil { - _ = dbs.Close() - return nil, nil, nil, nil, gossip.BlockProc{}, nil, fmt.Errorf("failed to apply genesis state: %v", err) - } - _ = dbs.Close() - setGenesisComplete(chaindataDir) - } - // Compact DBs after first launch - if genesisProc { - genesisProducers, _ := SupportedDBs(chaindataDir, cfg.DBs.GenesisCache) - for typ, p := range genesisProducers { - for _, name := range p.Names() { - if err := compactDB(typ, name, p); err != nil { - return nil, nil, nil, nil, gossip.BlockProc{}, nil, err - } - } - } - } - // Check DBs are synced - { - err := CheckStateInitialized(chaindataDir, cfg.DBs) - if err != nil { - return nil, nil, nil, nil, gossip.BlockProc{}, nil, err - } - } - // Migration - { - runtimeProducers, _ := SupportedDBs(chaindataDir, cfg.DBs.RuntimeCache) - dbs, err := MakeDirectMultiProducer(runtimeProducers, cfg.DBs.Routing) - if err != nil { - return nil, nil, nil, nil, gossip.BlockProc{}, nil, err - } - - // drop previous epoch DBs, which do not survive restart - epoch := getEpoch(dbs, cfg) - leDB, err := dbs.OpenDB(fmt.Sprintf("lachesis-%d", epoch)) - if err != nil { - _ = dbs.Close() - return nil, nil, nil, nil, gossip.BlockProc{}, nil, err - } - _ = leDB.Close() - leDB.Drop() - goDB, err := dbs.OpenDB(fmt.Sprintf("gossip-%d", epoch)) - if err != nil { - _ = dbs.Close() - return nil, nil, nil, nil, gossip.BlockProc{}, nil, err - } - _ = goDB.Close() - goDB.Drop() - - err = migrate(dbs, cfg) - _ = dbs.Close() - if err != nil { - return nil, nil, nil, nil, gossip.BlockProc{}, nil, fmt.Errorf("failed to migrate state: %v", err) - } - } - // Live setup - - runtimeProducers, runtimeScopedProducers := SupportedDBs(chaindataDir, cfg.DBs.RuntimeCache) - // open flushable DBs - dbs, err := MakeMultiProducer(runtimeProducers, runtimeScopedProducers, cfg.DBs.Routing) - if err != nil { - return nil, nil, nil, nil, gossip.BlockProc{}, nil, err - } - - gdb, cdb := getStores(dbs, cfg) - defer func() { - if err != nil { - gdb.Close() - cdb.Close() - dbs.Close() - } - }() - - // compare genesis with the input - genesisID := gdb.GetGenesisID() - if genesisID == nil { - err = errors.New("malformed chainstore: genesis ID is not written") - return nil, nil, nil, nil, gossip.BlockProc{}, dbs.Close, err - } - if g != nil { - if *genesisID != g.GenesisID { - err = &GenesisMismatchError{*genesisID, g.GenesisID} - return nil, nil, nil, nil, gossip.BlockProc{}, dbs.Close, err - } - } - - engine, vecClock, blockProc, err := rawMakeEngine(gdb, cdb, nil, cfg) - if err != nil { - err = fmt.Errorf("failed to make engine: %v", err) - return nil, nil, nil, nil, gossip.BlockProc{}, dbs.Close, err - } - - if genesisProc { - err = gdb.Commit() - if err != nil { - err = fmt.Errorf("failed to commit DBs: %v", err) - return nil, nil, nil, nil, gossip.BlockProc{}, dbs.Close, err - } - } - - return engine, vecClock, gdb, cdb, blockProc, dbs.Close, nil -} - -// MakeEngine makes consensus engine from config. -func MakeEngine(chaindataDir string, g *genesis.Genesis, cfg Configs) (*abft.Lachesis, *vecmt.Index, *gossip.Store, *abft.Store, gossip.BlockProc, func() error) { - // Legacy DBs migrate - if cfg.DBs.MigrationMode != "reformat" && cfg.DBs.MigrationMode != "rebuild" && cfg.DBs.MigrationMode != "" { - utils.Fatalf("MigrationMode must be 'reformat' or 'rebuild'") - } - if !isEmpty(path.Join(chaindataDir, "gossip")) { - MakeDBDirs(chaindataDir) - genesisProducers, _ := SupportedDBs(chaindataDir, cfg.DBs.GenesisCache) - dbs, err := MakeDirectMultiProducer(genesisProducers, cfg.DBs.Routing) - if err != nil { - utils.Fatalf("Failed to make engine: %v", err) - } - err = migrateLegacyDBs(chaindataDir, dbs, cfg.DBs.MigrationMode, cfg.DBs.Routing) - _ = dbs.Close() - if err != nil { - utils.Fatalf("Failed to migrate state: %v", err) - } - } - - dropAllDBsIfInterrupted(chaindataDir) - firstLaunch := isEmpty(chaindataDir) - MakeDBDirs(chaindataDir) - - engine, vecClock, gdb, cdb, blockProc, closeDBs, err := makeEngine(chaindataDir, g, firstLaunch, cfg) - if err != nil { - if firstLaunch { - dropAllDBs(chaindataDir) - } - utils.Fatalf("Failed to make engine: %v", err) - } - - rules := gdb.GetRules() - genesisID := gdb.GetGenesisID() - if firstLaunch { - log.Info("Applied genesis state", "name", rules.Name, "id", rules.NetworkID, "genesis", genesisID.String()) - } else { - log.Info("Genesis is already written", "name", rules.Name, "id", rules.NetworkID, "genesis", genesisID.String()) - } - - return engine, vecClock, gdb, cdb, blockProc, closeDBs -} - -// SetAccountKey sets key into accounts manager and unlocks it with pswd. -func SetAccountKey( - am *accounts.Manager, key *ecdsa.PrivateKey, pswd string, -) ( - acc accounts.Account, -) { - kss := am.Backends(keystore.KeyStoreType) - if len(kss) < 1 { - log.Crit("Keystore is not found") - return - } - ks := kss[0].(*keystore.KeyStore) - - acc = accounts.Account{ - Address: crypto.PubkeyToAddress(key.PublicKey), - } - - imported, err := ks.ImportECDSA(key, pswd) - if err == nil { - acc = imported - } else if err.Error() != "account already exists" { - log.Crit("Failed to import key", "err", err) - } - - err = ks.Unlock(acc, pswd) - if err != nil { - log.Crit("failed to unlock key", "err", err) - } - - return -} diff --git a/evm/go-x1/integration/bench_db_flush_test.go b/evm/go-x1/integration/bench_db_flush_test.go deleted file mode 100644 index acca6ea..0000000 --- a/evm/go-x1/integration/bench_db_flush_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package integration - -import ( - "io/ioutil" - "os" - "testing" - - "github.com/Fantom-foundation/lachesis-base/abft" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" - "github.com/ethereum/go-ethereum/common" - - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/utils" - "github.com/Fantom-foundation/go-opera/vecmt" -) - -func BenchmarkFlushDBs(b *testing.B) { - dir := tmpDir("flush_bench") - defer os.RemoveAll(dir) - genStore := makefakegenesis.FakeGenesisStore(1, utils.ToFtm(1), utils.ToFtm(1)) - g := genStore.Genesis() - _, _, store, s2, _, closeDBs := MakeEngine(dir, &g, Configs{ - Opera: gossip.DefaultConfig(cachescale.Identity), - OperaStore: gossip.DefaultStoreConfig(cachescale.Identity), - Lachesis: abft.DefaultConfig(), - LachesisStore: abft.DefaultStoreConfig(cachescale.Identity), - VectorClock: vecmt.DefaultConfig(cachescale.Identity), - DBs: DefaultDBsConfig(cachescale.Identity.U64, 512), - }) - defer closeDBs() - defer store.Close() - defer s2.Close() - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() - n := idx.Block(0) - randUint32s := func() []uint32 { - arr := make([]uint32, 128) - for i := 0; i < len(arr); i++ { - arr[i] = uint32(i) ^ (uint32(n) << 16) ^ 0xd0ad884e - } - return []uint32{uint32(n), uint32(n) + 1, uint32(n) + 2} - } - for !store.IsCommitNeeded() { - store.SetBlock(n, &inter.Block{ - Time: inter.Timestamp(n << 32), - Atropos: hash.Event{}, - Events: hash.Events{}, - Txs: []common.Hash{}, - InternalTxs: []common.Hash{}, - SkippedTxs: randUint32s(), - GasUsed: uint64(n) << 24, - Root: hash.Hash{}, - }) - n++ - } - b.StartTimer() - err := store.Commit() - if err != nil { - b.Fatal(err) - } - } -} - -func tmpDir(name string) string { - dir, err := ioutil.TempDir("", name) - if err != nil { - panic(err) - } - return dir -} diff --git a/evm/go-x1/integration/db.go b/evm/go-x1/integration/db.go deleted file mode 100644 index cf79110..0000000 --- a/evm/go-x1/integration/db.go +++ /dev/null @@ -1,182 +0,0 @@ -package integration - -import ( - "io" - "io/ioutil" - "os" - "path" - "strings" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/flaggedproducer" - "github.com/Fantom-foundation/lachesis-base/kvdb/flushable" - "github.com/Fantom-foundation/lachesis-base/kvdb/leveldb" - "github.com/Fantom-foundation/lachesis-base/kvdb/multidb" - "github.com/Fantom-foundation/lachesis-base/kvdb/pebble" - "github.com/Fantom-foundation/lachesis-base/utils/fmtfilter" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" - - "github.com/Fantom-foundation/go-opera/gossip" - "github.com/Fantom-foundation/go-opera/utils/dbutil/asyncflushproducer" - "github.com/Fantom-foundation/go-opera/utils/dbutil/dbcounter" -) - -type DBsConfig struct { - Routing RoutingConfig - RuntimeCache DBsCacheConfig - GenesisCache DBsCacheConfig - MigrationMode string -} - -type DBCacheConfig struct { - Cache uint64 - Fdlimit uint64 -} - -type DBsCacheConfig struct { - Table map[string]DBCacheConfig -} - -func SupportedDBs(chaindataDir string, cfg DBsCacheConfig) (map[multidb.TypeName]kvdb.IterableDBProducer, map[multidb.TypeName]kvdb.FullDBProducer) { - if chaindataDir == "inmemory" || chaindataDir == "" { - chaindataDir, _ = ioutil.TempDir("", "opera-tmp") - } - cacher, err := DbCacheFdlimit(cfg) - if err != nil { - utils.Fatalf("Failed to create DB cacher: %v", err) - } - - leveldbFsh := dbcounter.Wrap(leveldb.NewProducer(path.Join(chaindataDir, "leveldb-fsh"), cacher), true) - leveldbFlg := dbcounter.Wrap(leveldb.NewProducer(path.Join(chaindataDir, "leveldb-flg"), cacher), true) - leveldbDrc := dbcounter.Wrap(leveldb.NewProducer(path.Join(chaindataDir, "leveldb-drc"), cacher), true) - pebbleFsh := dbcounter.Wrap(pebble.NewProducer(path.Join(chaindataDir, "pebble-fsh"), cacher), true) - pebbleFlg := dbcounter.Wrap(pebble.NewProducer(path.Join(chaindataDir, "pebble-flg"), cacher), true) - pebbleDrc := dbcounter.Wrap(pebble.NewProducer(path.Join(chaindataDir, "pebble-drc"), cacher), true) - - if metrics.Enabled { - leveldbFsh = WrapDatabaseWithMetrics(leveldbFsh) - leveldbFlg = WrapDatabaseWithMetrics(leveldbFlg) - leveldbDrc = WrapDatabaseWithMetrics(leveldbDrc) - pebbleFsh = WrapDatabaseWithMetrics(pebbleFsh) - pebbleFlg = WrapDatabaseWithMetrics(pebbleFlg) - pebbleDrc = WrapDatabaseWithMetrics(pebbleDrc) - } - - return map[multidb.TypeName]kvdb.IterableDBProducer{ - "leveldb-fsh": leveldbFsh, - "leveldb-flg": leveldbFlg, - "leveldb-drc": leveldbDrc, - "pebble-fsh": pebbleFsh, - "pebble-flg": pebbleFlg, - "pebble-drc": pebbleDrc, - }, map[multidb.TypeName]kvdb.FullDBProducer{ - "leveldb-fsh": flushable.NewSyncedPool(leveldbFsh, FlushIDKey), - "leveldb-flg": flaggedproducer.Wrap(leveldbFlg, FlushIDKey), - "leveldb-drc": &DummyScopedProducer{leveldbDrc}, - "pebble-fsh": asyncflushproducer.Wrap(flushable.NewSyncedPool(pebbleFsh, FlushIDKey), 200000), - "pebble-flg": flaggedproducer.Wrap(pebbleFlg, FlushIDKey), - "pebble-drc": &DummyScopedProducer{pebbleDrc}, - } -} - -func DbCacheFdlimit(cfg DBsCacheConfig) (func(string) (int, int), error) { - fmts := make([]func(req string) (string, error), 0, len(cfg.Table)) - fmtsCaches := make([]DBCacheConfig, 0, len(cfg.Table)) - exactTable := make(map[string]DBCacheConfig, len(cfg.Table)) - // build scanf filters - for name, cache := range cfg.Table { - if !strings.ContainsRune(name, '%') { - exactTable[name] = cache - } else { - fn, err := fmtfilter.CompileFilter(name, name) - if err != nil { - return nil, err - } - fmts = append(fmts, fn) - fmtsCaches = append(fmtsCaches, cache) - } - } - return func(name string) (int, int) { - // try exact match - if cache, ok := cfg.Table[name]; ok { - return int(cache.Cache), int(cache.Fdlimit) - } - // try regexp - for i, fn := range fmts { - if _, err := fn(name); err == nil { - return int(fmtsCaches[i].Cache), int(fmtsCaches[i].Fdlimit) - } - } - // default - return int(cfg.Table[""].Cache), int(cfg.Table[""].Fdlimit) - }, nil -} - -func isEmpty(dir string) bool { - f, err := os.Open(dir) - if err != nil { - return true - } - defer f.Close() - _, err = f.Readdirnames(1) - if err == io.EOF { - return true - } - return false -} - -func dropAllDBs(chaindataDir string) { - _ = os.RemoveAll(chaindataDir) -} - -func dropAllDBsIfInterrupted(chaindataDir string) { - if isInterrupted(chaindataDir) { - log.Info("Restarting genesis processing") - dropAllDBs(chaindataDir) - } -} - -type GossipStoreAdapter struct { - *gossip.Store -} - -func (g *GossipStoreAdapter) GetEvent(id hash.Event) dag.Event { - e := g.Store.GetEvent(id) - if e == nil { - return nil - } - return e -} - -func MakeDBDirs(chaindataDir string) { - dbs, _ := SupportedDBs(chaindataDir, DBsCacheConfig{}) - for typ := range dbs { - if err := os.MkdirAll(path.Join(chaindataDir, string(typ)), 0700); err != nil { - utils.Fatalf("Failed to create chaindata/leveldb directory: %v", err) - } - } -} - -type DummyScopedProducer struct { - kvdb.IterableDBProducer -} - -func (d DummyScopedProducer) NotFlushedSizeEst() int { - return 0 -} - -func (d DummyScopedProducer) Flush(_ []byte) error { - return nil -} - -func (d DummyScopedProducer) Initialize(_ []string, flushID []byte) ([]byte, error) { - return flushID, nil -} - -func (d DummyScopedProducer) Close() error { - return nil -} diff --git a/evm/go-x1/integration/diskusage.go b/evm/go-x1/integration/diskusage.go deleted file mode 100644 index f957904..0000000 --- a/evm/go-x1/integration/diskusage.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build !windows && !openbsd -// +build !windows,!openbsd - -package integration - -import ( - "fmt" - - "golang.org/x/sys/unix" -) - -func getFreeDiskSpace(path string) (uint64, error) { - var stat unix.Statfs_t - if err := unix.Statfs(path, &stat); err != nil { - return 0, fmt.Errorf("failed to call Statfs: %v", err) - } - - // Available blocks * size per block = available space in bytes - var bavail = stat.Bavail - if stat.Bavail < 0 { - // FreeBSD can have a negative number of blocks available - // because of the grace limit. - bavail = 0 - } - //nolint:unconvert - return uint64(bavail) * uint64(stat.Bsize), nil -} diff --git a/evm/go-x1/integration/diskusage_openbsd.go b/evm/go-x1/integration/diskusage_openbsd.go deleted file mode 100644 index e8ec60c..0000000 --- a/evm/go-x1/integration/diskusage_openbsd.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build openbsd -// +build openbsd - -package integration - -import ( - "fmt" - - "golang.org/x/sys/unix" -) - -func getFreeDiskSpace(path string) (uint64, error) { - var stat unix.Statfs_t - if err := unix.Statfs(path, &stat); err != nil { - return 0, fmt.Errorf("failed to call Statfs: %v", err) - } - - // Available blocks * size per block = available space in bytes - var bavail = stat.F_bavail - // Not sure if the following check is necessary for OpenBSD - if stat.F_bavail < 0 { - // FreeBSD can have a negative number of blocks available - // because of the grace limit. - bavail = 0 - } - //nolint:unconvert - return uint64(bavail) * uint64(stat.F_bsize), nil -} diff --git a/evm/go-x1/integration/diskusage_windows.go b/evm/go-x1/integration/diskusage_windows.go deleted file mode 100644 index 8195fc5..0000000 --- a/evm/go-x1/integration/diskusage_windows.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package integration - -import ( - "fmt" - - "golang.org/x/sys/windows" -) - -func getFreeDiskSpace(path string) (uint64, error) { - - cwd, err := windows.UTF16PtrFromString(path) - if err != nil { - return 0, fmt.Errorf("failed to call UTF16PtrFromString: %v", err) - } - - var freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes uint64 - if err := windows.GetDiskFreeSpaceEx(cwd, &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes); err != nil { - return 0, fmt.Errorf("failed to call GetDiskFreeSpaceEx: %v", err) - } - - return freeBytesAvailableToCaller, nil -} diff --git a/evm/go-x1/integration/legacy_migrate.go b/evm/go-x1/integration/legacy_migrate.go deleted file mode 100644 index f38f2a2..0000000 --- a/evm/go-x1/integration/legacy_migrate.go +++ /dev/null @@ -1,338 +0,0 @@ -package integration - -import ( - "errors" - "fmt" - "os" - "path" - "strings" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/batched" - "github.com/Fantom-foundation/lachesis-base/kvdb/leveldb" - "github.com/Fantom-foundation/lachesis-base/kvdb/pebble" - "github.com/Fantom-foundation/lachesis-base/kvdb/skipkeys" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/go-opera/utils/dbutil/autocompact" - "github.com/Fantom-foundation/go-opera/utils/dbutil/compactdb" -) - -func lastKey(db kvdb.Store) []byte { - var start []byte - for { - for b := 0xff; b >= 0; b-- { - if !isEmptyDB(table.New(db, append(start, byte(b)))) { - start = append(start, byte(b)) - break - } - if b == 0 { - return start - } - } - } -} - -type transformTask struct { - openSrc func() kvdb.Store - openDst func() kvdb.Store - name string - dir string - dropSrc bool -} - -func transform(m transformTask) error { - openDst := func() *batched.Store { - return batched.Wrap(autocompact.Wrap2M(m.openDst(), opt.GiB, 16*opt.GiB, true, "")) - } - openSrc := func() *batched.Store { - return batched.Wrap(m.openSrc()) - } - src := openSrc() - defer func() { - _ = src.Close() - if m.dropSrc { - src.Drop() - } - }() - if isEmptyDB(src) { - return nil - } - dst := openDst() - - const batchKeys = 5000000 - keys := make([][]byte, 0, batchKeys) - // start from previously written data, if any - it := src.NewIterator(nil, lastKey(dst)) - defer func() { - // wrap with func because DBs may be reopened below - it.Release() - _ = dst.Close() - }() - log.Info("Transforming DB layout", "db", m.name) - for next := true; next; { - for len(keys) < batchKeys { - next = it.Next() - if !next { - break - } - err := dst.Put(it.Key(), it.Value()) - if err != nil { - utils.Fatalf("Failed to put: %v", err) - } - keys = append(keys, common.CopyBytes(it.Key())) - } - err := dst.Flush() - if err != nil { - utils.Fatalf("Failed to flush: %v", err) - } - freeSpace, err := getFreeDiskSpace(m.dir) - if err != nil { - log.Error("Failed to retrieve free disk space", "err", err) - } else if freeSpace < 20*opt.GiB { - return errors.New("not enough disk space") - } else if len(keys) > 0 && freeSpace < 100*opt.GiB { - log.Warn("Running out of disk space. Trimming source DB records", "space_GB", freeSpace/opt.GiB) - _, _ = dst.Stat("async_flush") - // release iterator so that DB could release data - it.Release() - // erase data from src - for _, k := range keys { - _ = src.Delete(k) - } - _ = src.Compact(keys[0], keys[len(keys)-1]) - // reopen source DB too if it doesn't release data - if freeSpace < 50*opt.GiB { - _ = src.Close() - src = openSrc() - } - it = src.NewIterator(nil, keys[len(keys)-1]) - } - keys = keys[:0] - } - // compact the new DB - if err := compactdb.Compact(dst, m.name, 16*opt.GiB); err != nil { - return err - } - return nil -} - -func mustTransform(m transformTask) { - err := transform(m) - if err != nil { - utils.Fatalf(err.Error()) - } -} - -func isEmptyDB(db kvdb.Iteratee) bool { - it := db.NewIterator(nil, nil) - defer it.Release() - return !it.Next() -} - -func fileExists(filename string) bool { - info, err := os.Stat(filename) - if err != nil { - return false - } - return !info.IsDir() -} - -type closebaleTable struct { - *table.Table - backend kvdb.Store -} - -func (s *closebaleTable) Close() error { - return s.backend.Close() -} - -func (s *closebaleTable) Drop() { - s.backend.Drop() -} - -func newClosableTable(db kvdb.Store, prefix []byte) *closebaleTable { - return &closebaleTable{ - Table: table.New(db, prefix), - backend: db, - } -} - -func translateGossipPrefix(p byte) byte { - if p == byte('!') { - return byte('S') - } - if p == byte('@') { - return byte('R') - } - if p == byte('#') { - return byte('Q') - } - if p == byte('$') { - return byte('T') - } - if p == byte('%') { - return byte('J') - } - if p == byte('^') { - return byte('E') - } - if p == byte('&') { - return byte('I') - } - if p == byte('*') { - return byte('G') - } - if p == byte('(') { - return byte('F') - } - return p -} - -func migrateLegacyDBs(chaindataDir string, dbs kvdb.FlushableDBProducer, mode string, layout RoutingConfig) error { - { // didn't erase the brackets to avoid massive code changes - // migrate DB layout - cacheFn, err := DbCacheFdlimit(DBsCacheConfig{ - Table: map[string]DBCacheConfig{ - "": { - Cache: 1024 * opt.MiB, - Fdlimit: uint64(utils.MakeDatabaseHandles() / 2), - }, - }, - }) - if err != nil { - return err - } - var oldDBs kvdb.IterableDBProducer - var oldDBsType string - if fileExists(path.Join(chaindataDir, "gossip", "LOG")) { - oldDBs = leveldb.NewProducer(chaindataDir, cacheFn) - oldDBsType = "ldb" - } else { - oldDBs = pebble.NewProducer(chaindataDir, cacheFn) - oldDBsType = "pbl" - } - openOldDB := func(name string) kvdb.Store { - db, err := oldDBs.OpenDB(name) - if err != nil { - utils.Fatalf("Failed to open %s old DB: %v", name, err) - } - return db - } - openNewDB := func(name string) kvdb.Store { - db, err := dbs.OpenDB(name) - if err != nil { - utils.Fatalf("Failed to open %s DB: %v", name, err) - } - return db - } - - switch mode { - case "rebuild": - // move lachesis, lachesis-%d and gossip-%d DBs - for _, name := range oldDBs.Names() { - if strings.HasPrefix(name, "lachesis") || strings.HasPrefix(name, "gossip-") { - mustTransform(transformTask{ - openSrc: func() kvdb.Store { - return skipkeys.Wrap(openOldDB(name), MetadataPrefix) - }, - openDst: func() kvdb.Store { - return openNewDB(name) - }, - name: name, - dir: chaindataDir, - }) - } - } - - // move gossip DB - - // move logs - mustTransform(transformTask{ - openSrc: func() kvdb.Store { - return newClosableTable(openOldDB("gossip"), []byte("Lr")) - }, - openDst: func() kvdb.Store { - return openNewDB("evm-logs/r") - }, - name: "gossip/Lr", - dir: chaindataDir, - }) - mustTransform(transformTask{ - openSrc: func() kvdb.Store { - return newClosableTable(openOldDB("gossip"), []byte("Lt")) - }, - openDst: func() kvdb.Store { - return openNewDB("evm-logs/t") - }, - name: "gossip/Lt", - dir: chaindataDir, - }) - - // skip 0 prefix, as it contains flushID - for b := 1; b <= 0xff; b++ { - if b == int('L') { - // logs are already moved above - continue - } - mustTransform(transformTask{ - openSrc: func() kvdb.Store { - return newClosableTable(openOldDB("gossip"), []byte{byte(b)}) - }, - openDst: func() kvdb.Store { - if b == int('M') || b == int('r') || b == int('x') || b == int('X') { - return openNewDB("evm/" + string([]byte{byte(b)})) - } else { - return openNewDB("gossip/" + string([]byte{translateGossipPrefix(byte(b))})) - } - }, - name: fmt.Sprintf("gossip/%c", rune(b)), - dir: chaindataDir, - dropSrc: b == 0xff, - }) - } - case "reformat": - if oldDBsType == "ldb" { - if !layout.Equal(LdbLegacyRoutingConfig()) { - return errors.New("reformatting DBs: missing --db.preset=legacy-ldb flag") - } - err = os.Rename(path.Join(chaindataDir, "gossip"), path.Join(chaindataDir, "leveldb-fsh", "main")) - if err != nil { - return err - } - for _, name := range oldDBs.Names() { - if strings.HasPrefix(name, "lachesis") || strings.HasPrefix(name, "gossip-") { - err = os.Rename(path.Join(chaindataDir, name), path.Join(chaindataDir, "leveldb-fsh", name)) - if err != nil { - return err - } - } - } - } else { - if !layout.Equal(PblLegacyRoutingConfig()) { - return errors.New("reformatting DBs: missing --db.preset=legacy-pbl flag") - } - err = os.Rename(path.Join(chaindataDir, "gossip"), path.Join(chaindataDir, "pebble-fsh", "main")) - if err != nil { - return err - } - for _, name := range oldDBs.Names() { - if strings.HasPrefix(name, "lachesis") || strings.HasPrefix(name, "gossip-") { - err = os.Rename(path.Join(chaindataDir, name), path.Join(chaindataDir, "pebble-fsh", name)) - if err != nil { - return err - } - } - } - } - default: - return errors.New("missing --db.migration.mode flag") - } - } - - return nil -} diff --git a/evm/go-x1/integration/makefakegenesis/genesis.go b/evm/go-x1/integration/makefakegenesis/genesis.go deleted file mode 100644 index 16d4222..0000000 --- a/evm/go-x1/integration/makefakegenesis/genesis.go +++ /dev/null @@ -1,200 +0,0 @@ -package makefakegenesis - -import ( - "crypto/ecdsa" - "github.com/ethereum/go-ethereum/log" - "math/big" - "time" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" - "github.com/Fantom-foundation/lachesis-base/lachesis" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/integration/makegenesis" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/drivertype" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver/drivercall" - "github.com/Fantom-foundation/go-opera/opera/contracts/driverauth" - "github.com/Fantom-foundation/go-opera/opera/contracts/evmwriter" - "github.com/Fantom-foundation/go-opera/opera/contracts/netinit" - netinitcall "github.com/Fantom-foundation/go-opera/opera/contracts/netinit/netinitcalls" - "github.com/Fantom-foundation/go-opera/opera/contracts/sfc" - "github.com/Fantom-foundation/go-opera/opera/contracts/sfclib" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/opera/genesis/gpos" - "github.com/Fantom-foundation/go-opera/opera/genesisstore" -) - -var ( - FakeGenesisTime = inter.Timestamp(1608600000 * time.Second) -) - -// FakeKey gets n-th fake private key. -func FakeKey(n idx.ValidatorID) *ecdsa.PrivateKey { - return evmcore.FakeKey(uint32(n)) -} - -func FakeGenesisStore(num idx.Validator, balance, stake *big.Int) *genesisstore.Store { - return FakeGenesisStoreWithRules(num, balance, stake, opera.FakeNetRules()) -} - -func FakeGenesisStoreWithRules(num idx.Validator, balance, stake *big.Int, rules opera.Rules) *genesisstore.Store { - return FakeGenesisStoreWithRulesAndStart(num, balance, stake, rules, 2, 1) -} - -func FakeGenesisStoreWithRulesAndStart(num idx.Validator, balance, stake *big.Int, rules opera.Rules, epoch idx.Epoch, block idx.Block) *genesisstore.Store { - builder := makegenesis.NewGenesisBuilder(memorydb.NewProducer("")) - - validators := GetFakeValidators(num) - - // add balances to validators - var delegations []drivercall.Delegation - for _, val := range validators { - log.Info("Validator", "address", val.Address, "pk", val.PubKey, "id", val.ID) - - builder.AddBalance(val.Address, balance) - delegations = append(delegations, drivercall.Delegation{ - Address: val.Address, - ValidatorID: val.ID, - Stake: stake, - LockedStake: new(big.Int), - LockupFromEpoch: 0, - LockupEndTime: 0, - LockupDuration: 0, - EarlyUnlockPenalty: new(big.Int), - Rewards: new(big.Int), - }) - } - - // deploy essential contracts - // pre deploy NetworkInitializer - builder.SetCode(netinit.ContractAddress, netinit.GetContractBin()) - // pre deploy NodeDriver - builder.SetCode(driver.ContractAddress, driver.GetContractBin()) - // pre deploy NodeDriverAuth - builder.SetCode(driverauth.ContractAddress, driverauth.GetContractBin()) - // pre deploy SFC - builder.SetCode(sfc.ContractAddress, sfc.GetContractBin()) - // pre deploy SFCLib - builder.SetCode(sfclib.ContractAddress, sfclib.GetContractBin()) - // set non-zero code for pre-compiled contracts - builder.SetCode(evmwriter.ContractAddress, []byte{0}) - - builder.SetCurrentEpoch(ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{ - BlockState: iblockproc.BlockState{ - LastBlock: iblockproc.BlockCtx{ - Idx: block - 1, - Time: FakeGenesisTime, - Atropos: hash.Event{}, - }, - FinalizedStateRoot: hash.Hash{}, - EpochGas: 0, - EpochCheaters: lachesis.Cheaters{}, - CheatersWritten: 0, - ValidatorStates: make([]iblockproc.ValidatorBlockState, 0), - NextValidatorProfiles: make(map[idx.ValidatorID]drivertype.Validator), - DirtyRules: nil, - AdvanceEpochs: 0, - }, - EpochState: iblockproc.EpochState{ - Epoch: epoch - 1, - EpochStart: FakeGenesisTime, - PrevEpochStart: FakeGenesisTime - 1, - EpochStateRoot: hash.Zero, - Validators: pos.NewBuilder().Build(), - ValidatorStates: make([]iblockproc.ValidatorEpochState, 0), - ValidatorProfiles: make(map[idx.ValidatorID]drivertype.Validator), - Rules: rules, - }, - }, - Idx: epoch - 1, - }) - - var owner common.Address - if num != 0 { - owner = validators[0].Address - } - - blockProc := makegenesis.DefaultBlockProc() - genesisTxs := GetGenesisTxs(epoch-2, validators, builder.TotalSupply(), delegations, owner) - err := builder.ExecuteGenesisTxs(blockProc, genesisTxs) - if err != nil { - panic(err) - } - - return builder.Build(genesis.Header{ - GenesisID: builder.CurrentHash(), - NetworkID: rules.NetworkID, - NetworkName: rules.Name, - }) -} - -func txBuilder() func(calldata []byte, addr common.Address) *types.Transaction { - nonce := uint64(0) - return func(calldata []byte, addr common.Address) *types.Transaction { - tx := types.NewTransaction(nonce, addr, common.Big0, 1e10, common.Big0, calldata) - nonce++ - return tx - } -} - -func GetGenesisTxs(sealedEpoch idx.Epoch, validators gpos.Validators, totalSupply *big.Int, delegations []drivercall.Delegation, driverOwner common.Address) types.Transactions { - buildTx := txBuilder() - internalTxs := make(types.Transactions, 0, 15) - // initialization - calldata := netinitcall.InitializeAll(sealedEpoch, totalSupply, sfc.ContractAddress, sfclib.ContractAddress, driverauth.ContractAddress, driver.ContractAddress, evmwriter.ContractAddress, driverOwner) - internalTxs = append(internalTxs, buildTx(calldata, netinit.ContractAddress)) - // push genesis validators - for _, v := range validators { - calldata := drivercall.SetGenesisValidator(v) - internalTxs = append(internalTxs, buildTx(calldata, driver.ContractAddress)) - } - // push genesis delegations - for _, delegation := range delegations { - calldata := drivercall.SetGenesisDelegation(delegation) - internalTxs = append(internalTxs, buildTx(calldata, driver.ContractAddress)) - } - return internalTxs -} - -func GetFakeValidators(num idx.Validator) gpos.Validators { - validators := make(gpos.Validators, 0, num) - - for i := idx.ValidatorID(1); i <= idx.ValidatorID(num); i++ { - key := FakeKey(i) - addr := crypto.PubkeyToAddress(key.PublicKey) - pubkeyraw := crypto.FromECDSAPub(&key.PublicKey) - - publicKey := validatorpk.PubKey{ - Raw: pubkeyraw, - Type: validatorpk.Types.Secp256k1, - } - - log.Info("publicKey", "key", publicKey, "addr", addr) - - validators = append(validators, gpos.Validator{ - ID: i, - Address: addr, - PubKey: publicKey, - CreationTime: FakeGenesisTime, - CreationEpoch: 0, - DeactivatedTime: 0, - DeactivatedEpoch: 0, - Status: 0, - }) - } - - return validators -} diff --git a/evm/go-x1/integration/makegenesis/genesis.go b/evm/go-x1/integration/makegenesis/genesis.go deleted file mode 100644 index 07aee09..0000000 --- a/evm/go-x1/integration/makegenesis/genesis.go +++ /dev/null @@ -1,261 +0,0 @@ -package makegenesis - -import ( - "bytes" - "errors" - "io" - "math/big" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/evmcore" - "github.com/Fantom-foundation/go-opera/gossip/blockproc" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/drivermodule" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/eventmodule" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/evmmodule" - "github.com/Fantom-foundation/go-opera/gossip/blockproc/sealmodule" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/opera/genesisstore" - "github.com/Fantom-foundation/go-opera/utils/iodb" -) - -type GenesisBuilder struct { - dbs kvdb.DBProducer - - tmpEvmStore *evmstore.Store - tmpStateDB *state.StateDB - - totalSupply *big.Int - - blocks []ibr.LlrIdxFullBlockRecord - epochs []ier.LlrIdxFullEpochRecord - currentEpoch ier.LlrIdxFullEpochRecord -} - -type BlockProc struct { - SealerModule blockproc.SealerModule - TxListenerModule blockproc.TxListenerModule - PreTxTransactor blockproc.TxTransactor - PostTxTransactor blockproc.TxTransactor - EventsModule blockproc.ConfirmedEventsModule - EVMModule blockproc.EVM -} - -func DefaultBlockProc() BlockProc { - return BlockProc{ - SealerModule: sealmodule.New(), - TxListenerModule: drivermodule.NewDriverTxListenerModule(), - PreTxTransactor: drivermodule.NewDriverTxPreTransactor(), - PostTxTransactor: drivermodule.NewDriverTxTransactor(), - EventsModule: eventmodule.New(), - EVMModule: evmmodule.New(), - } -} - -func (b *GenesisBuilder) GetStateDB() *state.StateDB { - if b.tmpStateDB == nil { - tmpEvmStore := evmstore.NewStore(b.dbs, evmstore.LiteStoreConfig()) - b.tmpStateDB, _ = tmpEvmStore.StateDB(hash.Zero) - } - return b.tmpStateDB -} - -func (b *GenesisBuilder) AddBalance(acc common.Address, balance *big.Int) { - b.tmpStateDB.AddBalance(acc, balance) - b.totalSupply.Add(b.totalSupply, balance) -} - -func (b *GenesisBuilder) SetCode(acc common.Address, code []byte) { - b.tmpStateDB.SetCode(acc, code) -} - -func (b *GenesisBuilder) SetNonce(acc common.Address, nonce uint64) { - b.tmpStateDB.SetNonce(acc, nonce) -} - -func (b *GenesisBuilder) SetStorage(acc common.Address, key, val common.Hash) { - b.tmpStateDB.SetState(acc, key, val) -} - -func (b *GenesisBuilder) AddBlock(br ibr.LlrIdxFullBlockRecord) { - b.blocks = append(b.blocks, br) -} - -func (b *GenesisBuilder) AddEpoch(er ier.LlrIdxFullEpochRecord) { - b.epochs = append(b.epochs, er) -} - -func (b *GenesisBuilder) SetCurrentEpoch(er ier.LlrIdxFullEpochRecord) { - b.currentEpoch = er -} - -func (b *GenesisBuilder) TotalSupply() *big.Int { - return b.totalSupply -} - -func (b *GenesisBuilder) CurrentHash() hash.Hash { - er := b.epochs[len(b.epochs)-1] - return er.Hash() -} - -func NewGenesisBuilder(dbs kvdb.DBProducer) *GenesisBuilder { - tmpEvmStore := evmstore.NewStore(dbs, evmstore.LiteStoreConfig()) - statedb, _ := tmpEvmStore.StateDB(hash.Zero) - return &GenesisBuilder{ - dbs: dbs, - tmpEvmStore: tmpEvmStore, - tmpStateDB: statedb, - totalSupply: new(big.Int), - } -} - -type dummyHeaderReturner struct { -} - -func (d dummyHeaderReturner) GetHeader(common.Hash, uint64) *evmcore.EvmHeader { - return &evmcore.EvmHeader{} -} - -func (b *GenesisBuilder) ExecuteGenesisTxs(blockProc BlockProc, genesisTxs types.Transactions) error { - bs, es := b.currentEpoch.BlockState.Copy(), b.currentEpoch.EpochState.Copy() - - blockCtx := iblockproc.BlockCtx{ - Idx: bs.LastBlock.Idx + 1, - Time: bs.LastBlock.Time + 1, - Atropos: hash.Event{}, - } - - sealer := blockProc.SealerModule.Start(blockCtx, bs, es) - sealing := true - txListener := blockProc.TxListenerModule.Start(blockCtx, bs, es, b.tmpStateDB) - evmProcessor := blockProc.EVMModule.Start(blockCtx, b.tmpStateDB, dummyHeaderReturner{}, func(l *types.Log) { - txListener.OnNewLog(l) - }, es.Rules, es.Rules.EvmChainConfig([]opera.UpgradeHeight{ - { - Upgrades: es.Rules.Upgrades, - Height: 0, - }, - })) - - // Execute genesis transactions - evmProcessor.Execute(genesisTxs) - bs = txListener.Finalize() - - // Execute pre-internal transactions - preInternalTxs := blockProc.PreTxTransactor.PopInternalTxs(blockCtx, bs, es, sealing, b.tmpStateDB) - evmProcessor.Execute(preInternalTxs) - bs = txListener.Finalize() - - // Seal epoch if requested - if sealing { - sealer.Update(bs, es) - bs, es = sealer.SealEpoch() - txListener.Update(bs, es) - } - - // Execute post-internal transactions - internalTxs := blockProc.PostTxTransactor.PopInternalTxs(blockCtx, bs, es, sealing, b.tmpStateDB) - evmProcessor.Execute(internalTxs) - - evmBlock, skippedTxs, receipts := evmProcessor.Finalize() - for _, r := range receipts { - if r.Status == 0 { - return errors.New("genesis transaction reverted") - } - } - if len(skippedTxs) != 0 { - return errors.New("genesis transaction is skipped") - } - bs = txListener.Finalize() - bs.FinalizedStateRoot = hash.Hash(evmBlock.Root) - - bs.LastBlock = blockCtx - - prettyHash := func(root hash.Hash) hash.Event { - e := inter.MutableEventPayload{} - // for nice-looking ID - e.SetEpoch(es.Epoch) - e.SetLamport(1) - // actual data hashed - e.SetExtra(root[:]) - - return e.Build().ID() - } - receiptsStorage := make([]*types.ReceiptForStorage, len(receipts)) - for i, r := range receipts { - receiptsStorage[i] = (*types.ReceiptForStorage)(r) - } - // add block - b.blocks = append(b.blocks, ibr.LlrIdxFullBlockRecord{ - LlrFullBlockRecord: ibr.LlrFullBlockRecord{ - Atropos: prettyHash(bs.FinalizedStateRoot), - Root: bs.FinalizedStateRoot, - Txs: evmBlock.Transactions, - Receipts: receiptsStorage, - Time: blockCtx.Time, - GasUsed: evmBlock.GasUsed, - }, - Idx: blockCtx.Idx, - }) - // add epoch - b.currentEpoch = ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{ - BlockState: bs, - EpochState: es, - }, - Idx: es.Epoch, - } - b.epochs = append(b.epochs, b.currentEpoch) - - return b.tmpEvmStore.Commit(bs.LastBlock.Idx, bs.FinalizedStateRoot, true) -} - -type memFile struct { - *bytes.Buffer -} - -func (f *memFile) Close() error { - *f = memFile{} - return nil -} - -func (b *GenesisBuilder) Build(head genesis.Header) *genesisstore.Store { - return genesisstore.NewStore(func(name string) (io.Reader, error) { - buf := &memFile{bytes.NewBuffer(nil)} - if name == genesisstore.BlocksSection(0) { - for i := len(b.blocks) - 1; i >= 0; i-- { - _ = rlp.Encode(buf, b.blocks[i]) - } - return buf, nil - } - if name == genesisstore.EpochsSection(0) { - for i := len(b.epochs) - 1; i >= 0; i-- { - _ = rlp.Encode(buf, b.epochs[i]) - } - return buf, nil - } - if name == genesisstore.EvmSection(0) { - it := b.tmpEvmStore.EvmDb.NewIterator(nil, nil) - defer it.Release() - _ = iodb.Write(buf, it) - } - if buf.Len() == 0 { - return nil, errors.New("not found") - } - return buf, nil - }, head, func() error { - *b = GenesisBuilder{} - return nil - }) -} diff --git a/evm/go-x1/integration/maketestnetgenesis/genesis.go b/evm/go-x1/integration/maketestnetgenesis/genesis.go deleted file mode 100644 index caaa7f0..0000000 --- a/evm/go-x1/integration/maketestnetgenesis/genesis.go +++ /dev/null @@ -1,173 +0,0 @@ -package maketestnetgenesis - -import ( - "github.com/Fantom-foundation/go-opera/integration/makegenesis" - "github.com/Fantom-foundation/go-opera/inter/drivertype" - "github.com/Fantom-foundation/go-opera/inter/iblockproc" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver" - "github.com/Fantom-foundation/go-opera/opera/contracts/driver/drivercall" - "github.com/Fantom-foundation/go-opera/opera/contracts/driverauth" - "github.com/Fantom-foundation/go-opera/opera/contracts/evmwriter" - "github.com/Fantom-foundation/go-opera/opera/contracts/netinit" - netinitcall "github.com/Fantom-foundation/go-opera/opera/contracts/netinit/netinitcalls" - "github.com/Fantom-foundation/go-opera/opera/contracts/sfc" - "github.com/Fantom-foundation/go-opera/opera/contracts/sfclib" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/opera/genesis/gpos" - "github.com/Fantom-foundation/go-opera/opera/genesisstore" - futils "github.com/Fantom-foundation/go-opera/utils" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" - "github.com/Fantom-foundation/lachesis-base/lachesis" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "math/big" -) - -func TestnetGenesisStore() *genesisstore.Store { - return TestnetGenesisStoreWithRules(futils.ToFtm(opera.TestnetStartBalance), futils.ToFtm(opera.TestnetStartStake), opera.TestNetRules()) -} - -func TestnetGenesisStoreWithRules(balance, stake *big.Int, rules opera.Rules) *genesisstore.Store { - return TestnetGenesisStoreWithRulesAndStart(balance, stake, rules, 2, 1) -} - -func TestnetGenesisStoreWithRulesAndStart(balance, stake *big.Int, rules opera.Rules, epoch idx.Epoch, block idx.Block) *genesisstore.Store { - builder := makegenesis.NewGenesisBuilder(memorydb.NewProducer("")) - - validators := GetTestnetValidators() - - // add balances to validators - var delegations []drivercall.Delegation - for _, val := range validators { - log.Info("Validator", "address", val.Address, "pk", val.PubKey, "id", val.ID) - builder.AddBalance(val.Address, balance) - delegations = append(delegations, drivercall.Delegation{ - Address: val.Address, - ValidatorID: val.ID, - Stake: stake, - LockedStake: new(big.Int), - LockupFromEpoch: 0, - LockupEndTime: 0, - LockupDuration: 0, - EarlyUnlockPenalty: new(big.Int), - Rewards: new(big.Int), - }) - } - - // deploy essential contracts - // pre deploy NetworkInitializer - builder.SetCode(netinit.ContractAddress, netinit.GetContractBin()) - // pre deploy NodeDriver - builder.SetCode(driver.ContractAddress, driver.GetContractBin()) - // pre deploy NodeDriverAuth - builder.SetCode(driverauth.ContractAddress, driverauth.GetContractBin()) - // pre deploy SFC - builder.SetCode(sfc.ContractAddress, sfc.GetContractBin()) - // pre deploy SFCLib - builder.SetCode(sfclib.ContractAddress, sfclib.GetContractBin()) - // set non-zero code for pre-compiled contracts - builder.SetCode(evmwriter.ContractAddress, []byte{0}) - - builder.SetCurrentEpoch(ier.LlrIdxFullEpochRecord{ - LlrFullEpochRecord: ier.LlrFullEpochRecord{ - BlockState: iblockproc.BlockState{ - LastBlock: iblockproc.BlockCtx{ - Idx: block - 1, - Time: opera.TestnetGenesisTime, - Atropos: hash.Event{}, - }, - FinalizedStateRoot: hash.Hash{}, - EpochGas: 0, - EpochCheaters: lachesis.Cheaters{}, - CheatersWritten: 0, - ValidatorStates: make([]iblockproc.ValidatorBlockState, 0), - NextValidatorProfiles: make(map[idx.ValidatorID]drivertype.Validator), - DirtyRules: nil, - AdvanceEpochs: 0, - }, - EpochState: iblockproc.EpochState{ - Epoch: epoch - 1, - EpochStart: opera.TestnetGenesisTime, - PrevEpochStart: opera.TestnetGenesisTime - 1, - EpochStateRoot: hash.Zero, - Validators: pos.NewBuilder().Build(), - ValidatorStates: make([]iblockproc.ValidatorEpochState, 0), - ValidatorProfiles: make(map[idx.ValidatorID]drivertype.Validator), - Rules: rules, - }, - }, - Idx: epoch - 1, - }) - - var owner = validators[0].Address - - blockProc := makegenesis.DefaultBlockProc() - genesisTxs := GetGenesisTxs(epoch-2, validators, builder.TotalSupply(), delegations, owner) - err := builder.ExecuteGenesisTxs(blockProc, genesisTxs) - if err != nil { - panic(err) - } - - return builder.Build(genesis.Header{ - GenesisID: builder.CurrentHash(), - NetworkID: rules.NetworkID, - NetworkName: rules.Name, - }) -} - -func txBuilder() func(calldata []byte, addr common.Address) *types.Transaction { - nonce := uint64(0) - return func(calldata []byte, addr common.Address) *types.Transaction { - tx := types.NewTransaction(nonce, addr, common.Big0, 1e10, common.Big0, calldata) - nonce++ - return tx - } -} - -func GetGenesisTxs(sealedEpoch idx.Epoch, validators gpos.Validators, totalSupply *big.Int, delegations []drivercall.Delegation, driverOwner common.Address) types.Transactions { - buildTx := txBuilder() - internalTxs := make(types.Transactions, 0, 15) - // initialization - calldata := netinitcall.InitializeAll(sealedEpoch, totalSupply, sfc.ContractAddress, sfclib.ContractAddress, driverauth.ContractAddress, driver.ContractAddress, evmwriter.ContractAddress, driverOwner) - internalTxs = append(internalTxs, buildTx(calldata, netinit.ContractAddress)) - // push genesis validators - for _, v := range validators { - calldata := drivercall.SetGenesisValidator(v) - internalTxs = append(internalTxs, buildTx(calldata, driver.ContractAddress)) - } - // push genesis delegations - for _, delegation := range delegations { - calldata := drivercall.SetGenesisDelegation(delegation) - internalTxs = append(internalTxs, buildTx(calldata, driver.ContractAddress)) - } - return internalTxs -} - -func GetTestnetValidators() gpos.Validators { - validators := make(gpos.Validators, 0, len(opera.GenesisValidators)-1) - - for id, genesisValidator := range opera.GenesisValidators { - validators = append(validators, gpos.Validator{ - ID: idx.ValidatorID(id + 1), - Address: common.HexToAddress(genesisValidator.AccountAddress), - PubKey: validatorpk.PubKey{ - Raw: common.Hex2Bytes(genesisValidator.ValidatorPubKey), - Type: validatorpk.Types.Secp256k1, - }, - CreationTime: opera.TestnetGenesisTime, - CreationEpoch: 0, - DeactivatedTime: 0, - DeactivatedEpoch: 0, - Status: 0, - }) - } - - return validators -} diff --git a/evm/go-x1/integration/metric.go b/evm/go-x1/integration/metric.go deleted file mode 100644 index 3e08995..0000000 --- a/evm/go-x1/integration/metric.go +++ /dev/null @@ -1,176 +0,0 @@ -package integration - -import ( - "fmt" - "regexp" - "strings" - "sync" - "time" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" -) - -const ( - // metricsGatheringInterval specifies the interval to retrieve leveldb database - // compaction, io and pause stats to report to the user. - metricsGatheringInterval = 3 * time.Second -) - -type DBProducerWithMetrics struct { - kvdb.IterableDBProducer -} - -type StoreWithMetrics struct { - kvdb.Store - - diskSizeGauge metrics.Gauge // Gauge for tracking the size of all the levels in the database - diskReadMeter metrics.Meter // Meter for measuring the effective amount of data read - diskWriteMeter metrics.Meter // Meter for measuring the effective amount of data written - - quitLock sync.Mutex // Mutex protecting the quit channel access - quitChan chan chan error // Quit channel to stop the metrics collection before closing the database - - log log.Logger // Contextual logger tracking the database path -} - -func WrapDatabaseWithMetrics(db kvdb.IterableDBProducer) kvdb.IterableDBProducer { - wrapper := &DBProducerWithMetrics{db} - return wrapper -} - -func WrapStoreWithMetrics(ds kvdb.Store) *StoreWithMetrics { - wrapper := &StoreWithMetrics{ - Store: ds, - quitChan: make(chan chan error), - } - return wrapper -} - -func (ds *StoreWithMetrics) Close() error { - ds.quitLock.Lock() - defer ds.quitLock.Unlock() - - if ds.quitChan != nil { - errc := make(chan error) - ds.quitChan <- errc - if err := <-errc; err != nil { - ds.log.Error("Metrics collection failed", "err", err) - } - ds.quitChan = nil - } - return ds.Store.Close() -} - -func (ds *StoreWithMetrics) meter(refresh time.Duration) { - // Create storage for iostats. - var iostats [2]float64 - - var ( - errc chan error - merr error - ) - - timer := time.NewTimer(refresh) - defer timer.Stop() - // Iterate ad infinitum and collect the stats - for i := 1; errc == nil && merr == nil; i++ { - // Retrieve the database size - diskSize, err := ds.Stat("disk.size") - if err != nil { - ds.log.Error("Failed to read database stats", "err", err) - merr = err - continue - } - var nDiskSize int64 - if n, err := fmt.Sscanf(diskSize, "%d", &nDiskSize); n != 1 || err != nil { - ds.log.Error("Bad syntax of disk size entry", "size", diskSize) - merr = err - continue - } - // Update all the disk size meters - if ds.diskSizeGauge != nil { - ds.diskSizeGauge.Update(nDiskSize) - } - - // Retrieve the database iostats. - ioStats, err := ds.Stat("iostats") - if err != nil { - ds.log.Error("Failed to read database iostats", "err", err) - merr = err - continue - } - var nRead, nWrite float64 - parts := strings.Split(ioStats, " ") - if len(parts) < 2 { - ds.log.Error("Bad syntax of ioStats", "ioStats", ioStats) - merr = fmt.Errorf("bad syntax of ioStats %s", ioStats) - continue - } - if n, err := fmt.Sscanf(parts[0], "Read(MB):%f", &nRead); n != 1 || err != nil { - ds.log.Error("Bad syntax of read entry", "entry", parts[0]) - merr = err - continue - } - if n, err := fmt.Sscanf(parts[1], "Write(MB):%f", &nWrite); n != 1 || err != nil { - log.Error("Bad syntax of write entry", "entry", parts[1]) - merr = err - continue - } - if ds.diskReadMeter != nil { - ds.diskReadMeter.Mark(int64((nRead - iostats[0]) * 1024 * 1024)) - } - if ds.diskWriteMeter != nil { - ds.diskWriteMeter.Mark(int64((nWrite - iostats[1]) * 1024 * 1024)) - } - iostats[0], iostats[1] = nRead, nWrite - - // Sleep a bit, then repeat the stats collection - select { - case errc = <-ds.quitChan: - // Quit requesting, stop hammering the database - case <-timer.C: - timer.Reset(refresh) - // Timeout, gather a new set of stats - } - } - if errc == nil { - errc = <-ds.quitChan - } - errc <- merr -} - -var tmpDbNameMask = regexp.MustCompile("^([A-z]+)(-[0-9]+)$") - -func genericNameOfTmpDB(name string) string { - match := tmpDbNameMask.FindStringSubmatch(name) - if len(match) == 3 { - return match[1] + "-tmp" - } else { - return name - } -} - -func (db *DBProducerWithMetrics) OpenDB(name string) (kvdb.Store, error) { - ds, err := db.IterableDBProducer.OpenDB(name) - if err != nil { - return nil, err - } - dm := WrapStoreWithMetrics(ds) - - name = genericNameOfTmpDB(name) - - dm.log = log.New("database", name) - - metric := "opera/chaindata/" + strings.ReplaceAll(name, "-", "_") - dm.diskReadMeter = metrics.GetOrRegisterMeter(metric+"/disk/read", nil) - dm.diskWriteMeter = metrics.GetOrRegisterMeter(metric+"/disk/write", nil) - // reset size metric as far as previous db will be dropped soon - metrics.Unregister(metric + "/disk/size") - dm.diskSizeGauge = metrics.NewRegisteredGauge(metric+"/disk/size", nil) - - // Start up the metrics gathering and return - go dm.meter(metricsGatheringInterval) - return dm, nil -} diff --git a/evm/go-x1/integration/metric_test.go b/evm/go-x1/integration/metric_test.go deleted file mode 100644 index edf7aa4..0000000 --- a/evm/go-x1/integration/metric_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package integration - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestGenericNameOfTmpDB(t *testing.T) { - require := require.New(t) - - for name, exp := range map[string]string{ - "": "", - "main": "main", - "main-single": "main-single", - "lachesis-0": "lachesis-tmp", - "lachesis-0999": "lachesis-tmp", - "gossip-50": "gossip-tmp", - "epoch-1": "epoch-tmp", - "xxx-1a": "xxx-1a", - "123": "123", - } { - got := genericNameOfTmpDB(name) - require.Equal(exp, got, name) - } -} diff --git a/evm/go-x1/integration/presets.go b/evm/go-x1/integration/presets.go deleted file mode 100644 index 9f848bf..0000000 --- a/evm/go-x1/integration/presets.go +++ /dev/null @@ -1,549 +0,0 @@ -package integration - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb/multidb" - "github.com/syndtr/goleveldb/leveldb/opt" -) - -var DefaultDBsConfig = Pbl1DBsConfig -var DefaultDBsConfigName = "pbl-1" - -/* - * pbl-1 config - */ - -func Pbl1DBsConfig(scale func(uint64) uint64, fdlimit uint64) DBsConfig { - return DBsConfig{ - Routing: Pbl1RoutingConfig(), - RuntimeCache: Pbl1RuntimeDBsCacheConfig(scale, fdlimit), - GenesisCache: Pbl1GenesisDBsCacheConfig(scale, fdlimit), - } -} - -func Pbl1RoutingConfig() RoutingConfig { - return RoutingConfig{ - Table: map[string]multidb.Route{ - "": { - Type: "pebble-fsh", - }, - "lachesis": { - Type: "pebble-fsh", - Name: "main", - Table: "C", - }, - "gossip": { - Type: "pebble-fsh", - Name: "main", - }, - "evm": { - Type: "pebble-fsh", - Name: "main", - }, - "gossip/e": { - Type: "pebble-fsh", - Name: "events", - }, - "evm/M": { - Type: "pebble-drc", - Name: "evm-data", - }, - "evm-logs": { - Type: "pebble-fsh", - Name: "evm-logs", - }, - "gossip-%d": { - Type: "leveldb-fsh", - Name: "epoch-%d", - Table: "G", - }, - "lachesis-%d": { - Type: "leveldb-fsh", - Name: "epoch-%d", - Table: "L", - NoDrop: true, - }, - }, - } -} - -func Pbl1RuntimeDBsCacheConfig(scale func(uint64) uint64, fdlimit uint64) DBsCacheConfig { - return DBsCacheConfig{ - Table: map[string]DBCacheConfig{ - "evm-data": { - Cache: scale(480 * opt.MiB), - Fdlimit: fdlimit*480/1400 + 1, - }, - "evm-logs": { - Cache: scale(260 * opt.MiB), - Fdlimit: fdlimit*260/1400 + 1, - }, - "main": { - Cache: scale(320 * opt.MiB), - Fdlimit: fdlimit*320/1400 + 1, - }, - "events": { - Cache: scale(240 * opt.MiB), - Fdlimit: fdlimit*240/1400 + 1, - }, - "epoch-%d": { - Cache: scale(100 * opt.MiB), - Fdlimit: fdlimit*100/1400 + 1, - }, - "": { - Cache: 64 * opt.MiB, - Fdlimit: fdlimit/100 + 1, - }, - }, - } -} - -func Pbl1GenesisDBsCacheConfig(scale func(uint64) uint64, fdlimit uint64) DBsCacheConfig { - return DBsCacheConfig{ - Table: map[string]DBCacheConfig{ - "main": { - Cache: scale(1000 * opt.MiB), - Fdlimit: fdlimit*1000/3000 + 1, - }, - "evm-data": { - Cache: scale(1000 * opt.MiB), - Fdlimit: fdlimit*1000/3000 + 1, - }, - "evm-logs": { - Cache: scale(1000 * opt.MiB), - Fdlimit: fdlimit*1000/3000 + 1, - }, - "events": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "epoch-%d": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "": { - Cache: 16 * opt.MiB, - Fdlimit: fdlimit/100 + 1, - }, - }, - } -} - -/* - * ldb-1 config - */ - -func Ldb1DBsConfig(scale func(uint64) uint64, fdlimit uint64) DBsConfig { - return DBsConfig{ - Routing: Ldb1RoutingConfig(), - RuntimeCache: Ldb1RuntimeDBsCacheConfig(scale, fdlimit), - GenesisCache: Ldb1GenesisDBsCacheConfig(scale, fdlimit), - } -} - -func Ldb1RoutingConfig() RoutingConfig { - return RoutingConfig{ - Table: map[string]multidb.Route{ - "": { - Type: "leveldb-fsh", - }, - "lachesis": { - Type: "leveldb-fsh", - Name: "main", - Table: "C", - }, - "gossip": { - Type: "leveldb-fsh", - Name: "main", - }, - "evm": { - Type: "leveldb-fsh", - Name: "main", - }, - "gossip/e": { - Type: "leveldb-fsh", - Name: "events", - }, - "evm/M": { - Type: "leveldb-drc", - Name: "evm-data", - }, - "evm-logs": { - Type: "leveldb-fsh", - Name: "evm-logs", - }, - "gossip-%d": { - Type: "leveldb-fsh", - Name: "epoch-%d", - Table: "G", - }, - "lachesis-%d": { - Type: "leveldb-fsh", - Name: "epoch-%d", - Table: "L", - NoDrop: true, - }, - }, - } -} - -func Ldb1RuntimeDBsCacheConfig(scale func(uint64) uint64, fdlimit uint64) DBsCacheConfig { - return DBsCacheConfig{ - Table: map[string]DBCacheConfig{ - "evm-data": { - Cache: scale(480 * opt.MiB), - Fdlimit: fdlimit*480/1400 + 1, - }, - "evm-logs": { - Cache: scale(260 * opt.MiB), - Fdlimit: fdlimit*260/1400 + 1, - }, - "main": { - Cache: scale(320 * opt.MiB), - Fdlimit: fdlimit*320/1400 + 1, - }, - "events": { - Cache: scale(240 * opt.MiB), - Fdlimit: fdlimit*240/1400 + 1, - }, - "epoch-%d": { - Cache: scale(100 * opt.MiB), - Fdlimit: fdlimit*100/1400 + 1, - }, - "": { - Cache: 64 * opt.MiB, - Fdlimit: fdlimit/100 + 1, - }, - }, - } -} - -func Ldb1GenesisDBsCacheConfig(scale func(uint64) uint64, fdlimit uint64) DBsCacheConfig { - return DBsCacheConfig{ - Table: map[string]DBCacheConfig{ - "main": { - Cache: scale(1000 * opt.MiB), - Fdlimit: fdlimit*1000/3000 + 1, - }, - "evm-data": { - Cache: scale(1000 * opt.MiB), - Fdlimit: fdlimit*1000/3000 + 1, - }, - "evm-logs": { - Cache: scale(1000 * opt.MiB), - Fdlimit: fdlimit*1000/3000 + 1, - }, - "events": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "epoch-%d": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "": { - Cache: 16 * opt.MiB, - Fdlimit: fdlimit/100 + 1, - }, - }, - } -} - -/* - * legacy-ldb config - */ - -func LdbLegacyDBsConfig(scale func(uint64) uint64, fdlimit uint64) DBsConfig { - return DBsConfig{ - Routing: LdbLegacyRoutingConfig(), - RuntimeCache: LdbLegacyRuntimeDBsCacheConfig(scale, fdlimit), - GenesisCache: LdbLegacyGenesisDBsCacheConfig(scale, fdlimit), - } -} - -func LdbLegacyRoutingConfig() RoutingConfig { - return RoutingConfig{ - Table: map[string]multidb.Route{ - "": { - Type: "leveldb-fsh", - }, - "lachesis": { - Type: "leveldb-fsh", - Name: "lachesis", - }, - "gossip": { - Type: "leveldb-fsh", - Name: "main", - }, - - "gossip/S": { - Type: "leveldb-fsh", - Name: "main", - Table: "!", - }, - "gossip/R": { - Type: "leveldb-fsh", - Name: "main", - Table: "@", - }, - "gossip/Q": { - Type: "leveldb-fsh", - Name: "main", - Table: "#", - }, - - "gossip/T": { - Type: "leveldb-fsh", - Name: "main", - Table: "$", - }, - "gossip/J": { - Type: "leveldb-fsh", - Name: "main", - Table: "%", - }, - "gossip/E": { - Type: "leveldb-fsh", - Name: "main", - Table: "^", - }, - - "gossip/I": { - Type: "leveldb-fsh", - Name: "main", - Table: "&", - }, - "gossip/G": { - Type: "leveldb-fsh", - Name: "main", - Table: "*", - }, - "gossip/F": { - Type: "leveldb-fsh", - Name: "main", - Table: "(", - }, - - "evm": { - Type: "leveldb-fsh", - Name: "main", - }, - "evm-logs": { - Type: "leveldb-fsh", - Name: "main", - Table: "L", - }, - "gossip-%d": { - Type: "leveldb-fsh", - Name: "gossip-%d", - }, - "lachesis-%d": { - Type: "leveldb-fsh", - Name: "lachesis-%d", - }, - }, - } -} - -func LdbLegacyRuntimeDBsCacheConfig(scale func(uint64) uint64, fdlimit uint64) DBsCacheConfig { - return DBsCacheConfig{ - Table: map[string]DBCacheConfig{ - "main": { - Cache: scale(850 * opt.MiB), - Fdlimit: fdlimit*850/1000 + 1, - }, - "lachesis": { - Cache: scale(20 * opt.MiB), - Fdlimit: fdlimit*20/1000 + 1, - }, - "gossip-%d": { - Cache: scale(50 * opt.MiB), - Fdlimit: fdlimit*50/1000 + 1, - }, - "lachesis-%d": { - Cache: scale(80 * opt.MiB), - Fdlimit: fdlimit*80/1000 + 1, - }, - "": { - Cache: 64 * opt.MiB, - Fdlimit: fdlimit/100 + 1, - }, - }, - } -} - -func LdbLegacyGenesisDBsCacheConfig(scale func(uint64) uint64, fdlimit uint64) DBsCacheConfig { - return DBsCacheConfig{ - Table: map[string]DBCacheConfig{ - "main": { - Cache: scale(3000 * opt.MiB), - Fdlimit: fdlimit*3000 + 1, - }, - "lachesis": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "gossip-%d": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "lachesis-%d": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "": { - Cache: 16 * opt.MiB, - Fdlimit: fdlimit/100 + 1, - }, - }, - } -} - -/* - * legacy-pbl config - */ - -func PblLegacyDBsConfig(scale func(uint64) uint64, fdlimit uint64) DBsConfig { - return DBsConfig{ - Routing: PblLegacyRoutingConfig(), - RuntimeCache: PblLegacyRuntimeDBsCacheConfig(scale, fdlimit), - GenesisCache: PblLegacyGenesisDBsCacheConfig(scale, fdlimit), - } -} - -func PblLegacyRoutingConfig() RoutingConfig { - return RoutingConfig{ - Table: map[string]multidb.Route{ - "": { - Type: "pebble-fsh", - }, - "lachesis": { - Type: "pebble-fsh", - Name: "lachesis", - }, - "gossip": { - Type: "pebble-fsh", - Name: "main", - }, - - "gossip/S": { - Type: "pebble-fsh", - Name: "main", - Table: "!", - }, - "gossip/R": { - Type: "pebble-fsh", - Name: "main", - Table: "@", - }, - "gossip/Q": { - Type: "pebble-fsh", - Name: "main", - Table: "#", - }, - - "gossip/T": { - Type: "pebble-fsh", - Name: "main", - Table: "$", - }, - "gossip/J": { - Type: "pebble-fsh", - Name: "main", - Table: "%", - }, - "gossip/E": { - Type: "pebble-fsh", - Name: "main", - Table: "^", - }, - - "gossip/I": { - Type: "pebble-fsh", - Name: "main", - Table: "&", - }, - "gossip/G": { - Type: "pebble-fsh", - Name: "main", - Table: "*", - }, - "gossip/F": { - Type: "pebble-fsh", - Name: "main", - Table: "(", - }, - - "evm": { - Type: "pebble-fsh", - Name: "main", - }, - "evm-logs": { - Type: "pebble-fsh", - Name: "main", - Table: "L", - }, - "gossip-%d": { - Type: "pebble-fsh", - Name: "gossip-%d", - }, - "lachesis-%d": { - Type: "pebble-fsh", - Name: "lachesis-%d", - }, - }, - } -} - -func PblLegacyRuntimeDBsCacheConfig(scale func(uint64) uint64, fdlimit uint64) DBsCacheConfig { - return DBsCacheConfig{ - Table: map[string]DBCacheConfig{ - "main": { - Cache: scale(950 * opt.MiB), - Fdlimit: fdlimit*950/1400 + 1, - }, - "lachesis": { - Cache: scale(150 * opt.MiB), - Fdlimit: fdlimit*150/1400 + 1, - }, - "gossip-%d": { - Cache: scale(150 * opt.MiB), - Fdlimit: fdlimit*150/1400 + 1, - }, - "lachesis-%d": { - Cache: scale(150 * opt.MiB), - Fdlimit: fdlimit*150/1400 + 1, - }, - "": { - Cache: 64 * opt.MiB, - Fdlimit: fdlimit/100 + 1, - }, - }, - } -} - -func PblLegacyGenesisDBsCacheConfig(scale func(uint64) uint64, fdlimit uint64) DBsCacheConfig { - return DBsCacheConfig{ - Table: map[string]DBCacheConfig{ - "main": { - Cache: scale(3000 * opt.MiB), - Fdlimit: fdlimit, - }, - "lachesis": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "gossip-%d": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "lachesis-%d": { - Cache: scale(1 * opt.MiB), - Fdlimit: fdlimit*1/3000 + 1, - }, - "": { - Cache: 16 * opt.MiB, - Fdlimit: fdlimit/100 + 1, - }, - }, - } -} diff --git a/evm/go-x1/integration/routing.go b/evm/go-x1/integration/routing.go deleted file mode 100644 index b253037..0000000 --- a/evm/go-x1/integration/routing.go +++ /dev/null @@ -1,65 +0,0 @@ -package integration - -import ( - "fmt" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/cachedproducer" - "github.com/Fantom-foundation/lachesis-base/kvdb/multidb" - "github.com/Fantom-foundation/lachesis-base/kvdb/skipkeys" - - "github.com/Fantom-foundation/go-opera/utils/dbutil/threads" -) - -type RoutingConfig struct { - Table map[string]multidb.Route -} - -func (a RoutingConfig) Equal(b RoutingConfig) bool { - if len(a.Table) != len(b.Table) { - return false - } - for k, v := range a.Table { - if b.Table[k] != v { - return false - } - } - return true -} - -func MakeMultiProducer(rawProducers map[multidb.TypeName]kvdb.IterableDBProducer, scopedProducers map[multidb.TypeName]kvdb.FullDBProducer, cfg RoutingConfig) (kvdb.FullDBProducer, error) { - cachedProducers := make(map[multidb.TypeName]kvdb.FullDBProducer) - var flushID []byte - var err error - for typ, producer := range scopedProducers { - flushID, err = producer.Initialize(rawProducers[typ].Names(), flushID) - if err != nil { - return nil, fmt.Errorf("failed to open existing databases: %v. Try to use 'db heal' to recover", err) - } - cachedProducers[typ] = cachedproducer.WrapAll(producer) - } - - p, err := makeMultiProducer(cachedProducers, cfg) - return threads.CountedFullDBProducer(p), err -} - -func MakeDirectMultiProducer(rawProducers map[multidb.TypeName]kvdb.IterableDBProducer, cfg RoutingConfig) (kvdb.FullDBProducer, error) { - dproducers := map[multidb.TypeName]kvdb.FullDBProducer{} - for typ, producer := range rawProducers { - dproducers[typ] = &DummyScopedProducer{producer} - } - return MakeMultiProducer(rawProducers, dproducers, cfg) -} - -func makeMultiProducer(scopedProducers map[multidb.TypeName]kvdb.FullDBProducer, cfg RoutingConfig) (kvdb.FullDBProducer, error) { - multi, err := multidb.NewProducer(scopedProducers, cfg.Table, TablesKey) - if err != nil { - return nil, fmt.Errorf("failed to construct multidb: %v", err) - } - - err = multi.Verify() - if err != nil { - return nil, fmt.Errorf("incompatible chainstore DB layout: %v. Try to use 'db transform' to recover", err) - } - return skipkeys.WrapAllProducer(multi, MetadataPrefix), nil -} diff --git a/evm/go-x1/integration/status.go b/evm/go-x1/integration/status.go deleted file mode 100644 index d817ac4..0000000 --- a/evm/go-x1/integration/status.go +++ /dev/null @@ -1,23 +0,0 @@ -package integration - -import ( - "os" - "path" - - "github.com/Fantom-foundation/go-opera/utils" -) - -func isInterrupted(chaindataDir string) bool { - return utils.FileExists(path.Join(chaindataDir, "unfinished")) -} - -func setGenesisProcessing(chaindataDir string) { - f, _ := os.Create(path.Join(chaindataDir, "unfinished")) - if f != nil { - _ = f.Close() - } -} - -func setGenesisComplete(chaindataDir string) { - _ = os.Remove(path.Join(chaindataDir, "unfinished")) -} diff --git a/evm/go-x1/inter/block.go b/evm/go-x1/inter/block.go deleted file mode 100644 index 70e9792..0000000 --- a/evm/go-x1/inter/block.go +++ /dev/null @@ -1,40 +0,0 @@ -package inter - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -type Block struct { - Time Timestamp - Atropos hash.Event - Events hash.Events - Txs []common.Hash // non event txs (received via genesis or LLR) - InternalTxs []common.Hash // DEPRECATED in favor of using only Txs fields and method internal.IsInternal - SkippedTxs []uint32 // indexes of skipped txs, starting from first tx of first event, ending with last tx of last event - GasUsed uint64 - Root hash.Hash -} - -func (b *Block) EstimateSize() int { - return (len(b.Events)+len(b.InternalTxs)+len(b.Txs)+1+1)*32 + len(b.SkippedTxs)*4 + 8 + 8 -} - -func FilterSkippedTxs(txs types.Transactions, skippedTxs []uint32) types.Transactions { - if len(skippedTxs) == 0 { - // short circuit if nothing to skip - return txs - } - skipCount := 0 - filteredTxs := make(types.Transactions, 0, len(txs)) - for i, tx := range txs { - if skipCount < len(skippedTxs) && skippedTxs[skipCount] == uint32(i) { - skipCount++ - } else { - filteredTxs = append(filteredTxs, tx) - } - } - - return filteredTxs -} diff --git a/evm/go-x1/inter/drivertype/driver_type.go b/evm/go-x1/inter/drivertype/driver_type.go deleted file mode 100644 index 610fc85..0000000 --- a/evm/go-x1/inter/drivertype/driver_type.go +++ /dev/null @@ -1,27 +0,0 @@ -package drivertype - -import ( - "math/big" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" -) - -var ( - // DoublesignBit is set if validator has a confirmed pair of fork events - DoublesignBit = uint64(1 << 7) - OkStatus = uint64(0) -) - -// Validator is the node-side representation of Driver validator -type Validator struct { - Weight *big.Int - PubKey validatorpk.PubKey -} - -// ValidatorAndID is pair Validator + ValidatorID -type ValidatorAndID struct { - ValidatorID idx.ValidatorID - Validator Validator -} diff --git a/evm/go-x1/inter/event.go b/evm/go-x1/inter/event.go deleted file mode 100644 index 21f6e17..0000000 --- a/evm/go-x1/inter/event.go +++ /dev/null @@ -1,344 +0,0 @@ -package inter - -import ( - "crypto/sha256" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" -) - -type EventI interface { - dag.Event - Version() uint8 - NetForkID() uint16 - CreationTime() Timestamp - MedianTime() Timestamp - PrevEpochHash() *hash.Hash - Extra() []byte - GasPowerLeft() GasPowerLeft - GasPowerUsed() uint64 - - HashToSign() hash.Hash - Locator() EventLocator - - // Payload-related fields - - AnyTxs() bool - AnyBlockVotes() bool - AnyEpochVote() bool - AnyMisbehaviourProofs() bool - PayloadHash() hash.Hash -} - -type EventLocator struct { - BaseHash hash.Hash - NetForkID uint16 - Epoch idx.Epoch - Seq idx.Event - Lamport idx.Lamport - Creator idx.ValidatorID - PayloadHash hash.Hash -} - -type SignedEventLocator struct { - Locator EventLocator - Sig Signature -} - -func AsSignedEventLocator(e EventPayloadI) SignedEventLocator { - return SignedEventLocator{ - Locator: e.Locator(), - Sig: e.Sig(), - } -} - -type EventPayloadI interface { - EventI - Sig() Signature - - Txs() types.Transactions - EpochVote() LlrEpochVote - BlockVotes() LlrBlockVotes - MisbehaviourProofs() []MisbehaviourProof -} - -var emptyPayloadHash1 = CalcPayloadHash(&MutableEventPayload{extEventData: extEventData{version: 1}}) - -func EmptyPayloadHash(version uint8) hash.Hash { - if version == 0 { - return hash.Hash(types.EmptyRootHash) - } else { - return emptyPayloadHash1 - } -} - -type baseEvent struct { - dag.BaseEvent -} - -type mutableBaseEvent struct { - dag.MutableBaseEvent -} - -type extEventData struct { - version uint8 - netForkID uint16 - creationTime Timestamp - medianTime Timestamp - prevEpochHash *hash.Hash - gasPowerLeft GasPowerLeft - gasPowerUsed uint64 - extra []byte - - anyTxs bool - anyBlockVotes bool - anyEpochVote bool - anyMisbehaviourProofs bool - payloadHash hash.Hash -} - -type sigData struct { - sig Signature -} - -type payloadData struct { - txs types.Transactions - misbehaviourProofs []MisbehaviourProof - - epochVote LlrEpochVote - blockVotes LlrBlockVotes -} - -type Event struct { - baseEvent - extEventData - - // cache - _baseHash *hash.Hash - _locatorHash *hash.Hash -} - -type SignedEvent struct { - Event - sigData -} - -type EventPayload struct { - SignedEvent - payloadData - - // cache - _size int -} - -type MutableEventPayload struct { - mutableBaseEvent - extEventData - sigData - payloadData -} - -func (e *Event) HashToSign() hash.Hash { - return *e._locatorHash -} - -func asLocator(basehash hash.Hash, e EventI) EventLocator { - return EventLocator{ - BaseHash: basehash, - NetForkID: e.NetForkID(), - Epoch: e.Epoch(), - Seq: e.Seq(), - Lamport: e.Lamport(), - Creator: e.Creator(), - PayloadHash: e.PayloadHash(), - } -} - -func (e *Event) Locator() EventLocator { - return asLocator(*e._baseHash, e) -} - -func (e *EventPayload) Size() int { - return e._size -} - -func (e *extEventData) Version() uint8 { return e.version } - -func (e *extEventData) NetForkID() uint16 { return e.netForkID } - -func (e *extEventData) CreationTime() Timestamp { return e.creationTime } - -func (e *extEventData) MedianTime() Timestamp { return e.medianTime } - -func (e *extEventData) PrevEpochHash() *hash.Hash { return e.prevEpochHash } - -func (e *extEventData) Extra() []byte { return e.extra } - -func (e *extEventData) PayloadHash() hash.Hash { return e.payloadHash } - -func (e *extEventData) AnyTxs() bool { return e.anyTxs } - -func (e *extEventData) AnyMisbehaviourProofs() bool { return e.anyMisbehaviourProofs } - -func (e *extEventData) AnyEpochVote() bool { return e.anyEpochVote } - -func (e *extEventData) AnyBlockVotes() bool { return e.anyBlockVotes } - -func (e *extEventData) GasPowerLeft() GasPowerLeft { return e.gasPowerLeft } - -func (e *extEventData) GasPowerUsed() uint64 { return e.gasPowerUsed } - -func (e *sigData) Sig() Signature { return e.sig } - -func (e *payloadData) Txs() types.Transactions { return e.txs } - -func (e *payloadData) MisbehaviourProofs() []MisbehaviourProof { return e.misbehaviourProofs } - -func (e *payloadData) BlockVotes() LlrBlockVotes { return e.blockVotes } - -func (e *payloadData) EpochVote() LlrEpochVote { return e.epochVote } - -func CalcTxHash(txs types.Transactions) hash.Hash { - return hash.Hash(types.DeriveSha(txs, trie.NewStackTrie(nil))) -} - -func CalcReceiptsHash(receipts []*types.ReceiptForStorage) hash.Hash { - hasher := sha256.New() - _ = rlp.Encode(hasher, receipts) - return hash.BytesToHash(hasher.Sum(nil)) -} - -func CalcMisbehaviourProofsHash(mps []MisbehaviourProof) hash.Hash { - hasher := sha256.New() - _ = rlp.Encode(hasher, mps) - return hash.BytesToHash(hasher.Sum(nil)) -} - -func CalcPayloadHash(e EventPayloadI) hash.Hash { - if e.Version() == 0 { - return CalcTxHash(e.Txs()) - } - return hash.Of(hash.Of(CalcTxHash(e.Txs()).Bytes(), CalcMisbehaviourProofsHash(e.MisbehaviourProofs()).Bytes()).Bytes(), hash.Of(e.EpochVote().Hash().Bytes(), e.BlockVotes().Hash().Bytes()).Bytes()) -} - -func (e *MutableEventPayload) SetVersion(v uint8) { e.version = v } - -func (e *MutableEventPayload) SetNetForkID(v uint16) { e.netForkID = v } - -func (e *MutableEventPayload) SetCreationTime(v Timestamp) { e.creationTime = v } - -func (e *MutableEventPayload) SetMedianTime(v Timestamp) { e.medianTime = v } - -func (e *MutableEventPayload) SetPrevEpochHash(v *hash.Hash) { e.prevEpochHash = v } - -func (e *MutableEventPayload) SetExtra(v []byte) { e.extra = v } - -func (e *MutableEventPayload) SetPayloadHash(v hash.Hash) { e.payloadHash = v } - -func (e *MutableEventPayload) SetGasPowerLeft(v GasPowerLeft) { e.gasPowerLeft = v } - -func (e *MutableEventPayload) SetGasPowerUsed(v uint64) { e.gasPowerUsed = v } - -func (e *MutableEventPayload) SetSig(v Signature) { e.sig = v } - -func (e *MutableEventPayload) SetTxs(v types.Transactions) { - e.txs = v - e.anyTxs = len(v) != 0 -} - -func (e *MutableEventPayload) SetMisbehaviourProofs(v []MisbehaviourProof) { - e.misbehaviourProofs = v - e.anyMisbehaviourProofs = len(v) != 0 -} - -func (e *MutableEventPayload) SetBlockVotes(v LlrBlockVotes) { - e.blockVotes = v - e.anyBlockVotes = len(v.Votes) != 0 -} - -func (e *MutableEventPayload) SetEpochVote(v LlrEpochVote) { - e.epochVote = v - e.anyEpochVote = v.Epoch != 0 && v.Vote != hash.Zero -} - -func calcEventID(h hash.Hash) (id [24]byte) { - copy(id[:], h[:24]) - return id -} - -func calcEventHashes(ser []byte, e EventI) (locator hash.Hash, base hash.Hash) { - base = hash.Of(ser) - if e.Version() < 1 { - return base, base - } - return asLocator(base, e).HashToSign(), base -} - -func (e *MutableEventPayload) calcHashes() (locator hash.Hash, base hash.Hash) { - b, _ := e.immutable().Event.MarshalBinary() - return calcEventHashes(b, e) -} - -func (e *MutableEventPayload) size() int { - b, err := e.immutable().MarshalBinary() - if err != nil { - panic("can't encode: " + err.Error()) - } - return len(b) -} - -func (e *MutableEventPayload) HashToSign() hash.Hash { - h, _ := e.calcHashes() - return h -} - -func (e *MutableEventPayload) Locator() EventLocator { - _, baseHash := e.calcHashes() - return asLocator(baseHash, e) -} - -func (e *MutableEventPayload) Size() int { - return e.size() -} - -func (e *MutableEventPayload) build(locatorHash hash.Hash, baseHash hash.Hash, size int) *EventPayload { - return &EventPayload{ - SignedEvent: SignedEvent{ - Event: Event{ - baseEvent: baseEvent{*e.MutableBaseEvent.Build(calcEventID(locatorHash))}, - extEventData: e.extEventData, - _baseHash: &baseHash, - _locatorHash: &locatorHash, - }, - sigData: e.sigData, - }, - payloadData: e.payloadData, - _size: size, - } -} - -func (e *MutableEventPayload) immutable() *EventPayload { - return e.build(hash.Hash{}, hash.Hash{}, 0) -} - -func (e *MutableEventPayload) Build() *EventPayload { - locatorHash, baseHash := e.calcHashes() - payloadSer, _ := e.immutable().MarshalBinary() - return e.build(locatorHash, baseHash, len(payloadSer)) -} - -func (l EventLocator) HashToSign() hash.Hash { - return hash.Of(l.BaseHash.Bytes(), bigendian.Uint16ToBytes(l.NetForkID), l.Epoch.Bytes(), l.Seq.Bytes(), l.Lamport.Bytes(), l.Creator.Bytes(), l.PayloadHash.Bytes()) -} - -func (l EventLocator) ID() hash.Event { - h := l.HashToSign() - copy(h[0:4], l.Epoch.Bytes()) - copy(h[4:8], l.Lamport.Bytes()) - return hash.Event(h) -} diff --git a/evm/go-x1/inter/event_serializer.go b/evm/go-x1/inter/event_serializer.go deleted file mode 100644 index d668191..0000000 --- a/evm/go-x1/inter/event_serializer.go +++ /dev/null @@ -1,558 +0,0 @@ -package inter - -import ( - "errors" - "io" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/utils/cser" -) - -var ( - ErrSerMalformedEvent = errors.New("serialization of malformed event") - ErrTooLowEpoch = errors.New("serialization of events with epoch<256 and version=0 is unsupported") - ErrUnknownVersion = errors.New("unknown serialization version") -) - -const MaxSerializationVersion = 1 - -const ProtocolMaxMsgSize = 10 * 1024 * 1024 - -func (e *Event) MarshalCSER(w *cser.Writer) error { - // version - if e.Version() > 0 { - w.BitsW.Write(2, 0) - w.U8(e.Version()) - } else { - if e.Epoch() < 256 { - return ErrTooLowEpoch - } - } - // base fields - if e.Version() > 0 { - w.U16(e.NetForkID()) - } - w.U32(uint32(e.Epoch())) - w.U32(uint32(e.Lamport())) - w.U32(uint32(e.Creator())) - w.U32(uint32(e.Seq())) - w.U32(uint32(e.Frame())) - w.U64(uint64(e.creationTime)) - medianTimeDiff := int64(e.creationTime) - int64(e.medianTime) - w.I64(medianTimeDiff) - // gas power - w.U64(e.gasPowerUsed) - w.U64(e.gasPowerLeft.Gas[0]) - w.U64(e.gasPowerLeft.Gas[1]) - // parents - w.U32(uint32(len(e.Parents()))) - for _, p := range e.Parents() { - if e.Lamport() < p.Lamport() { - return ErrSerMalformedEvent - } - // lamport difference - w.U32(uint32(e.Lamport() - p.Lamport())) - // without epoch and lamport - w.FixedBytes(p.Bytes()[8:]) - } - // prev epoch hash - w.Bool(e.prevEpochHash != nil) - if e.prevEpochHash != nil { - w.FixedBytes(e.prevEpochHash.Bytes()) - } - // tx hash - w.Bool(e.AnyTxs()) - if e.Version() > 0 { - w.Bool(e.AnyMisbehaviourProofs()) - w.Bool(e.AnyEpochVote()) - w.Bool(e.AnyBlockVotes()) - } - if e.AnyTxs() || e.AnyMisbehaviourProofs() || e.AnyBlockVotes() || e.AnyEpochVote() { - w.FixedBytes(e.PayloadHash().Bytes()) - } - // extra - w.SliceBytes(e.Extra()) - return nil -} - -// MarshalBinary implements encoding.BinaryMarshaller interface. -func (e *Event) MarshalBinary() ([]byte, error) { - return cser.MarshalBinaryAdapter(e.MarshalCSER) -} - -func eventUnmarshalCSER(r *cser.Reader, e *MutableEventPayload) (err error) { - // version - var version uint8 - if r.BitsR.View(2) == 0 { - r.BitsR.Read(2) - version = r.U8() - if version == 0 { - return cser.ErrNonCanonicalEncoding - } - } - if version > MaxSerializationVersion { - return ErrUnknownVersion - } - - // base fields - var netForkID uint16 - if version > 0 { - netForkID = r.U16() - } - epoch := r.U32() - lamport := r.U32() - creator := r.U32() - seq := r.U32() - frame := r.U32() - creationTime := r.U64() - medianTimeDiff := r.I64() - // gas power - gasPowerUsed := r.U64() - gasPowerLeft0 := r.U64() - gasPowerLeft1 := r.U64() - // parents - parentsNum := r.U32() - if parentsNum > ProtocolMaxMsgSize/24 { - return cser.ErrTooLargeAlloc - } - parents := make(hash.Events, 0, parentsNum) - for i := uint32(0); i < parentsNum; i++ { - // lamport difference - lamportDiff := r.U32() - // hash - h := [24]byte{} - r.FixedBytes(h[:]) - eID := dag.MutableBaseEvent{} - eID.SetEpoch(idx.Epoch(epoch)) - eID.SetLamport(idx.Lamport(lamport - lamportDiff)) - eID.SetID(h) - parents.Add(eID.ID()) - } - // prev epoch hash - var prevEpochHash *hash.Hash - prevEpochHashExists := r.Bool() - if prevEpochHashExists { - prevEpochHash_ := hash.Hash{} - r.FixedBytes(prevEpochHash_[:]) - prevEpochHash = &prevEpochHash_ - } - // tx hash - anyTxs := r.Bool() - anyMisbehaviourProofs := version > 0 && r.Bool() - anyEpochVote := version > 0 && r.Bool() - anyBlockVotes := version > 0 && r.Bool() - payloadHash := EmptyPayloadHash(version) - if anyTxs || anyMisbehaviourProofs || anyEpochVote || anyBlockVotes { - r.FixedBytes(payloadHash[:]) - if payloadHash == EmptyPayloadHash(version) { - return cser.ErrNonCanonicalEncoding - } - } - // extra - extra := r.SliceBytes(ProtocolMaxMsgSize) - - if version == 0 && epoch < 256 { - return ErrTooLowEpoch - } - - e.SetVersion(version) - e.SetNetForkID(netForkID) - e.SetEpoch(idx.Epoch(epoch)) - e.SetLamport(idx.Lamport(lamport)) - e.SetCreator(idx.ValidatorID(creator)) - e.SetSeq(idx.Event(seq)) - e.SetFrame(idx.Frame(frame)) - e.SetCreationTime(Timestamp(creationTime)) - e.SetMedianTime(Timestamp(int64(creationTime) - medianTimeDiff)) - e.SetGasPowerUsed(gasPowerUsed) - e.SetGasPowerLeft(GasPowerLeft{[2]uint64{gasPowerLeft0, gasPowerLeft1}}) - e.SetParents(parents) - e.SetPrevEpochHash(prevEpochHash) - e.anyTxs = anyTxs - e.anyBlockVotes = anyBlockVotes - e.anyEpochVote = anyEpochVote - e.anyMisbehaviourProofs = anyMisbehaviourProofs - e.SetPayloadHash(payloadHash) - e.SetExtra(extra) - return nil -} - -func MarshalTxsCSER(txs types.Transactions, w *cser.Writer) error { - // txs size - w.U56(uint64(txs.Len())) - // txs - for _, tx := range txs { - err := TransactionMarshalCSER(w, tx) - if err != nil { - return err - } - } - return nil -} - -func (bvs LlrBlockVotes) MarshalCSER(w *cser.Writer) error { - w.U64(uint64(bvs.Start)) - w.U32(uint32(bvs.Epoch)) - w.U32(uint32(len(bvs.Votes))) - for _, r := range bvs.Votes { - w.FixedBytes(r[:]) - } - return nil -} - -func (bvs *LlrBlockVotes) UnmarshalCSER(r *cser.Reader) error { - start := r.U64() - epoch := r.U32() - num := r.U32() - if num > ProtocolMaxMsgSize/32 { - return cser.ErrTooLargeAlloc - } - records := make([]hash.Hash, num) - for i := range records { - r.FixedBytes(records[i][:]) - } - bvs.Start = idx.Block(start) - bvs.Epoch = idx.Epoch(epoch) - bvs.Votes = records - return nil -} - -func (ers LlrEpochVote) MarshalCSER(w *cser.Writer) error { - w.U32(uint32(ers.Epoch)) - w.FixedBytes(ers.Vote[:]) - return nil -} - -func (ers *LlrEpochVote) UnmarshalCSER(r *cser.Reader) error { - epoch := r.U32() - record := hash.Hash{} - r.FixedBytes(record[:]) - ers.Epoch = idx.Epoch(epoch) - ers.Vote = record - return nil -} - -func (e *EventPayload) MarshalCSER(w *cser.Writer) error { - if e.AnyTxs() != (e.txs.Len() != 0) { - return ErrSerMalformedEvent - } - if e.AnyMisbehaviourProofs() != (len(e.misbehaviourProofs) != 0) { - return ErrSerMalformedEvent - } - if e.AnyEpochVote() != (e.epochVote.Epoch != 0) { - return ErrSerMalformedEvent - } - if e.AnyBlockVotes() != (len(e.blockVotes.Votes) != 0) { - return ErrSerMalformedEvent - } - err := e.Event.MarshalCSER(w) - if err != nil { - return err - } - w.FixedBytes(e.sig.Bytes()) - if e.AnyTxs() { - if e.Version() == 0 { - // Txs are serialized with CSER for legacy events - err = MarshalTxsCSER(e.txs, w) - if err != nil { - return err - } - } else { - b, err := rlp.EncodeToBytes(e.txs) - if err != nil { - return err - } - w.SliceBytes(b) - } - } - if e.AnyMisbehaviourProofs() { - b, err := rlp.EncodeToBytes(e.misbehaviourProofs) - if err != nil { - return err - } - w.SliceBytes(b) - } - if e.AnyEpochVote() { - err = e.EpochVote().MarshalCSER(w) - if err != nil { - return err - } - } - if e.AnyBlockVotes() { - err = e.BlockVotes().MarshalCSER(w) - if err != nil { - return err - } - } - return nil -} - -func (e *MutableEventPayload) UnmarshalCSER(r *cser.Reader) error { - err := eventUnmarshalCSER(r, e) - if err != nil { - return err - } - r.FixedBytes(e.sig[:]) - // txs - txs := make(types.Transactions, 0, 4) - if e.AnyTxs() { - if e.version == 0 { - // txs size - size := r.U56() - if size == 0 { - return cser.ErrNonCanonicalEncoding - } - if size > ProtocolMaxMsgSize/64 { - return cser.ErrTooLargeAlloc - } - for i := uint64(0); i < size; i++ { - tx, err := TransactionUnmarshalCSER(r) - if err != nil { - return err - } - txs = append(txs, tx) - } - } else { - b := r.SliceBytes(ProtocolMaxMsgSize) - err := rlp.DecodeBytes(b, &txs) - if err != nil { - return err - } - } - } - e.txs = txs - // mps - mps := make([]MisbehaviourProof, 0) - if e.AnyMisbehaviourProofs() { - b := r.SliceBytes(ProtocolMaxMsgSize) - err := rlp.DecodeBytes(b, &mps) - if err != nil { - return err - } - } - e.misbehaviourProofs = mps - // ev - ev := LlrEpochVote{} - if e.AnyEpochVote() { - err := ev.UnmarshalCSER(r) - if err != nil { - return err - } - if ev.Epoch == 0 { - return cser.ErrNonCanonicalEncoding - } - } - e.epochVote = ev - // bvs - bvs := LlrBlockVotes{Votes: make([]hash.Hash, 0, 2)} - if e.AnyBlockVotes() { - err := bvs.UnmarshalCSER(r) - if err != nil { - return err - } - if len(bvs.Votes) == 0 || bvs.Start == 0 || bvs.Epoch == 0 { - return cser.ErrNonCanonicalEncoding - } - } - e.blockVotes = bvs - return nil -} - -// MarshalBinary implements encoding.BinaryMarshaller interface. -func (e *EventPayload) MarshalBinary() ([]byte, error) { - return cser.MarshalBinaryAdapter(e.MarshalCSER) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaller interface. -func (e *MutableEventPayload) UnmarshalBinary(raw []byte) (err error) { - return cser.UnmarshalBinaryAdapter(raw, e.UnmarshalCSER) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaller interface. -func (e *EventPayload) UnmarshalBinary(raw []byte) (err error) { - mutE := MutableEventPayload{} - err = mutE.UnmarshalBinary(raw) - if err != nil { - return err - } - eventSer, _ := mutE.immutable().Event.MarshalBinary() - locatorHash, baseHash := calcEventHashes(eventSer, &mutE) - *e = *mutE.build(locatorHash, baseHash, len(raw)) - return nil -} - -// EncodeRLP implements rlp.Encoder interface. -func (e *EventPayload) EncodeRLP(w io.Writer) error { - bytes, err := e.MarshalBinary() - if err != nil { - return err - } - - err = rlp.Encode(w, &bytes) - - return err -} - -// DecodeRLP implements rlp.Decoder interface. -func (e *EventPayload) DecodeRLP(src *rlp.Stream) error { - bytes, err := src.Bytes() - if err != nil { - return err - } - - return e.UnmarshalBinary(bytes) -} - -// DecodeRLP implements rlp.Decoder interface. -func (e *MutableEventPayload) DecodeRLP(src *rlp.Stream) error { - bytes, err := src.Bytes() - if err != nil { - return err - } - - return e.UnmarshalBinary(bytes) -} - -// RPCMarshalEvent converts the given event to the RPC output . -func RPCMarshalEvent(e EventI) map[string]interface{} { - return map[string]interface{}{ - "version": hexutil.Uint64(e.Version()), - "networkVersion": hexutil.Uint64(e.NetForkID()), - "epoch": hexutil.Uint64(e.Epoch()), - "seq": hexutil.Uint64(e.Seq()), - "id": hexutil.Bytes(e.ID().Bytes()), - "frame": hexutil.Uint64(e.Frame()), - "creator": hexutil.Uint64(e.Creator()), - "prevEpochHash": e.PrevEpochHash(), - "parents": EventIDsToHex(e.Parents()), - "lamport": hexutil.Uint64(e.Lamport()), - "creationTime": hexutil.Uint64(e.CreationTime()), - "medianTime": hexutil.Uint64(e.MedianTime()), - "extraData": hexutil.Bytes(e.Extra()), - "payloadHash": hexutil.Bytes(e.PayloadHash().Bytes()), - "gasPowerLeft": map[string]interface{}{ - "shortTerm": hexutil.Uint64(e.GasPowerLeft().Gas[ShortTermGas]), - "longTerm": hexutil.Uint64(e.GasPowerLeft().Gas[LongTermGas]), - }, - "gasPowerUsed": hexutil.Uint64(e.GasPowerUsed()), - "anyTxs": e.AnyTxs(), - "anyMisbehaviourProofs": e.AnyMisbehaviourProofs(), - "anyEpochVote": e.AnyEpochVote(), - "anyBlockVotes": e.AnyBlockVotes(), - } -} - -// RPCUnmarshalEvent converts the RPC output to the header. -func RPCUnmarshalEvent(fields map[string]interface{}) EventI { - mustBeUint64 := func(name string) uint64 { - s := fields[name].(string) - return hexutil.MustDecodeUint64(s) - } - mustBeBytes := func(name string) []byte { - s := fields[name].(string) - return hexutil.MustDecode(s) - } - mustBeID := func(name string) (id [24]byte) { - s := fields[name].(string) - bb := hexutil.MustDecode(s) - copy(id[:], bb) - return - } - mustBeBool := func(name string) bool { - return fields[name].(bool) - } - mayBeHash := func(name string) *hash.Hash { - s, ok := fields[name].(string) - if !ok { - return nil - } - bb := hexutil.MustDecode(s) - h := hash.BytesToHash(bb) - return &h - } - - e := MutableEventPayload{} - - e.SetVersion(uint8(mustBeUint64("version"))) - e.SetNetForkID(uint16(mustBeUint64("networkVersion"))) - e.SetEpoch(idx.Epoch(mustBeUint64("epoch"))) - e.SetSeq(idx.Event(mustBeUint64("seq"))) - e.SetID(mustBeID("id")) - e.SetFrame(idx.Frame(mustBeUint64("frame"))) - e.SetCreator(idx.ValidatorID(mustBeUint64("creator"))) - e.SetPrevEpochHash(mayBeHash("prevEpochHash")) - e.SetParents(HexToEventIDs(fields["parents"].([]interface{}))) - e.SetLamport(idx.Lamport(mustBeUint64("lamport"))) - e.SetCreationTime(Timestamp(mustBeUint64("creationTime"))) - e.SetMedianTime(Timestamp(mustBeUint64("medianTime"))) - e.SetExtra(mustBeBytes("extraData")) - e.SetPayloadHash(*mayBeHash("payloadHash")) - e.SetGasPowerUsed(mustBeUint64("gasPowerUsed")) - e.anyTxs = mustBeBool("anyTxs") - e.anyMisbehaviourProofs = mustBeBool("anyMisbehaviourProofs") - e.anyEpochVote = mustBeBool("anyEpochVote") - e.anyBlockVotes = mustBeBool("anyBlockVotes") - - gas := GasPowerLeft{} - obj := fields["gasPowerLeft"].(map[string]interface{}) - gas.Gas[ShortTermGas] = hexutil.MustDecodeUint64(obj["shortTerm"].(string)) - gas.Gas[LongTermGas] = hexutil.MustDecodeUint64(obj["longTerm"].(string)) - e.SetGasPowerLeft(gas) - - return &e.Build().Event -} - -// RPCMarshalEventPayload converts the given event to the RPC output which depends on fullTx. If inclTx is true transactions are -// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain -// transaction hashes. -func RPCMarshalEventPayload(event EventPayloadI, inclTx bool, fullTx bool) (map[string]interface{}, error) { - fields := RPCMarshalEvent(event) - fields["size"] = hexutil.Uint64(event.Size()) - - if inclTx { - formatTx := func(tx *types.Transaction) (interface{}, error) { - return tx.Hash(), nil - } - if fullTx { - // TODO: full txs for events API - panic("is not implemented") - //formatTx = func(tx *types.Transaction) (interface{}, error) { - // return newRPCTransactionFromBlockHash(event, tx.Hash()), nil - //} - } - txs := event.Txs() - transactions := make([]interface{}, len(txs)) - var err error - for i, tx := range txs { - if transactions[i], err = formatTx(tx); err != nil { - return nil, err - } - } - - fields["transactions"] = transactions - } - - return fields, nil -} - -func EventIDsToHex(ids hash.Events) []hexutil.Bytes { - res := make([]hexutil.Bytes, len(ids)) - for i, id := range ids { - res[i] = hexutil.Bytes(id.Bytes()) - } - return res -} - -func HexToEventIDs(bb []interface{}) hash.Events { - res := make(hash.Events, len(bb)) - for i, b := range bb { - res[i] = hash.BytesToEvent(hexutil.MustDecode(b.(string))) - } - return res -} diff --git a/evm/go-x1/inter/event_serializer_test.go b/evm/go-x1/inter/event_serializer_test.go deleted file mode 100644 index 00c04af..0000000 --- a/evm/go-x1/inter/event_serializer_test.go +++ /dev/null @@ -1,406 +0,0 @@ -package inter - -import ( - "bytes" - "encoding/json" - "math" - "math/big" - "math/rand" - "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" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -func emptyEvent(ver uint8) EventPayload { - empty := MutableEventPayload{} - empty.SetVersion(ver) - if ver == 0 { - empty.SetEpoch(256) - } - empty.SetParents(hash.Events{}) - empty.SetExtra([]byte{}) - empty.SetTxs(types.Transactions{}) - empty.SetPayloadHash(EmptyPayloadHash(ver)) - return *empty.Build() -} - -func TestEventPayloadSerialization(t *testing.T) { - max := MutableEventPayload{} - max.SetEpoch(math.MaxUint32) - max.SetSeq(idx.Event(math.MaxUint32)) - max.SetLamport(idx.Lamport(math.MaxUint32)) - h := hash.BytesToEvent(bytes.Repeat([]byte{math.MaxUint8}, 32)) - max.SetParents(hash.Events{hash.Event(h), hash.Event(h), hash.Event(h)}) - max.SetPayloadHash(hash.Hash(h)) - max.SetSig(BytesToSignature(bytes.Repeat([]byte{math.MaxUint8}, SigSize))) - max.SetExtra(bytes.Repeat([]byte{math.MaxUint8}, 100)) - max.SetCreationTime(math.MaxUint64) - max.SetMedianTime(math.MaxUint64) - tx1 := types.NewTx(&types.LegacyTx{ - Nonce: math.MaxUint64, - GasPrice: h.Big(), - Gas: math.MaxUint64, - To: nil, - Value: h.Big(), - Data: []byte{}, - V: big.NewInt(0xff), - R: h.Big(), - S: h.Big(), - }) - tx2 := types.NewTx(&types.LegacyTx{ - Nonce: math.MaxUint64, - GasPrice: h.Big(), - Gas: math.MaxUint64, - To: &common.Address{}, - Value: h.Big(), - Data: max.extra, - V: big.NewInt(0xff), - R: h.Big(), - S: h.Big(), - }) - txs := types.Transactions{} - for i := 0; i < 200; i++ { - txs = append(txs, tx1) - txs = append(txs, tx2) - } - max.SetTxs(txs) - - ee := map[string]EventPayload{ - "empty0": emptyEvent(0), - "empty1": emptyEvent(1), - "max": *max.Build(), - "random": *FakeEvent(12, 1, 1, true), - } - - t.Run("ok", func(t *testing.T) { - require := require.New(t) - - for name, header0 := range ee { - buf, err := rlp.EncodeToBytes(&header0) - require.NoError(err) - - var header1 EventPayload - err = rlp.DecodeBytes(buf, &header1) - require.NoError(err, name) - - require.EqualValues(header0.extEventData, header1.extEventData, name) - require.EqualValues(header0.sigData, header1.sigData, name) - for i := range header0.payloadData.txs { - require.EqualValues(header0.payloadData.txs[i].Hash(), header1.payloadData.txs[i].Hash(), name) - } - require.EqualValues(header0.baseEvent, header1.baseEvent, name) - require.EqualValues(header0.ID(), header1.ID(), name) - require.EqualValues(header0.HashToSign(), header1.HashToSign(), name) - require.EqualValues(header0.Size(), header1.Size(), name) - } - }) - - t.Run("err", func(t *testing.T) { - require := require.New(t) - - for name, header0 := range ee { - bin, err := header0.MarshalBinary() - require.NoError(err, name) - - n := rand.Intn(len(bin) - len(header0.Extra()) - 1) - bin = bin[0:n] - - buf, err := rlp.EncodeToBytes(bin) - require.NoError(err, name) - - var header1 Event - err = rlp.DecodeBytes(buf, &header1) - require.Error(err, name) - } - }) -} - -func BenchmarkEventPayload_EncodeRLP_empty(b *testing.B) { - e := emptyEvent(0) - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - buf, err := rlp.EncodeToBytes(&e) - if err != nil { - b.Fatal(err) - } - b.ReportMetric(float64(len(buf)), "size") - } -} - -func BenchmarkEventPayload_EncodeRLP_NoPayload(b *testing.B) { - e := FakeEvent(0, 0, 0, false) - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - buf, err := rlp.EncodeToBytes(&e) - if err != nil { - b.Fatal(err) - } - b.ReportMetric(float64(len(buf)), "size") - } -} - -func BenchmarkEventPayload_EncodeRLP(b *testing.B) { - e := FakeEvent(1000, 0, 0, false) - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - buf, err := rlp.EncodeToBytes(&e) - if err != nil { - b.Fatal(err) - } - b.ReportMetric(float64(len(buf)), "size") - } -} - -func BenchmarkEventPayload_DecodeRLP_empty(b *testing.B) { - e := emptyEvent(0) - me := MutableEventPayload{} - - buf, err := rlp.EncodeToBytes(&e) - if err != nil { - b.Fatal(err) - } - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - err = rlp.DecodeBytes(buf, &me) - if err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEventPayload_DecodeRLP_NoPayload(b *testing.B) { - e := FakeEvent(0, 0, 0, false) - me := MutableEventPayload{} - - buf, err := rlp.EncodeToBytes(&e) - if err != nil { - b.Fatal(err) - } - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - err = rlp.DecodeBytes(buf, &me) - if err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkEventPayload_DecodeRLP(b *testing.B) { - e := FakeEvent(1000, 0, 0, false) - me := MutableEventPayload{} - - buf, err := rlp.EncodeToBytes(&e) - if err != nil { - b.Fatal(err) - } - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - err = rlp.DecodeBytes(buf, &me) - if err != nil { - b.Fatal(err) - } - } -} - -func TestEventRPCMarshaling(t *testing.T) { - t.Run("Event", func(t *testing.T) { - require := require.New(t) - for i := 0; i < 3; i++ { - var event0 EventI = &FakeEvent(i, i, i, i != 0).Event - mapping := RPCMarshalEvent(event0) - bb, err := json.Marshal(mapping) - require.NoError(err) - - mapping = make(map[string]interface{}) - err = json.Unmarshal(bb, &mapping) - require.NoError(err) - event1 := RPCUnmarshalEvent(mapping) - - require.Equal(event0, event1, i) - } - }) - - t.Run("EventPayload", func(t *testing.T) { - require := require.New(t) - for i := 0; i < 3; i++ { - var event0 = FakeEvent(i, i, i, i != 0) - mapping, err := RPCMarshalEventPayload(event0, true, false) - require.NoError(err) - bb, err := json.Marshal(mapping) - require.NoError(err) - - mapping = make(map[string]interface{}) - err = json.Unmarshal(bb, &mapping) - - event1 := RPCUnmarshalEvent(mapping) - require.Equal(&event0.SignedEvent.Event, event1, i) - } - }) -} - -func randBig(r *rand.Rand) *big.Int { - b := make([]byte, r.Intn(8)) - _, _ = r.Read(b) - if len(b) == 0 { - b = []byte{0} - } - return new(big.Int).SetBytes(b) -} - -func randAddr(r *rand.Rand) common.Address { - addr := common.Address{} - r.Read(addr[:]) - return addr -} - -func randBytes(r *rand.Rand, size int) []byte { - b := make([]byte, size) - r.Read(b) - return b -} - -func randHash(r *rand.Rand) hash.Hash { - return hash.BytesToHash(randBytes(r, 32)) -} - -func randAddrPtr(r *rand.Rand) *common.Address { - addr := randAddr(r) - return &addr -} - -func randAccessList(r *rand.Rand, maxAddrs, maxKeys int) types.AccessList { - accessList := make(types.AccessList, r.Intn(maxAddrs)) - for i := range accessList { - accessList[i].Address = randAddr(r) - accessList[i].StorageKeys = make([]common.Hash, r.Intn(maxKeys)) - for j := range accessList[i].StorageKeys { - r.Read(accessList[i].StorageKeys[j][:]) - } - } - return accessList -} - -// FakeEvent generates random event for testing purpose. -func FakeEvent(txsNum, mpsNum, bvsNum int, ersNum bool) *EventPayload { - r := rand.New(rand.NewSource(int64(0))) - random := &MutableEventPayload{} - random.SetVersion(1) - random.SetNetForkID(uint16(r.Uint32() >> 16)) - random.SetLamport(1000) - random.SetExtra([]byte{byte(r.Uint32())}) - random.SetSeq(idx.Event(r.Uint32() >> 8)) - random.SetCreator(idx.ValidatorID(r.Uint32())) - random.SetFrame(idx.Frame(r.Uint32() >> 16)) - random.SetCreationTime(Timestamp(r.Uint64())) - random.SetMedianTime(Timestamp(r.Uint64())) - random.SetGasPowerUsed(r.Uint64()) - random.SetGasPowerLeft(GasPowerLeft{[2]uint64{r.Uint64(), r.Uint64()}}) - txs := types.Transactions{} - for i := 0; i < txsNum; i++ { - h := hash.Hash{} - r.Read(h[:]) - if i%3 == 0 { - tx := types.NewTx(&types.LegacyTx{ - Nonce: r.Uint64(), - GasPrice: randBig(r), - Gas: 257 + r.Uint64(), - To: nil, - Value: randBig(r), - Data: randBytes(r, r.Intn(300)), - V: big.NewInt(int64(r.Intn(0xffffffff))), - R: h.Big(), - S: h.Big(), - }) - txs = append(txs, tx) - } else if i%3 == 1 { - tx := types.NewTx(&types.AccessListTx{ - ChainID: randBig(r), - Nonce: r.Uint64(), - GasPrice: randBig(r), - Gas: r.Uint64(), - To: randAddrPtr(r), - Value: randBig(r), - Data: randBytes(r, r.Intn(300)), - AccessList: randAccessList(r, 300, 300), - V: big.NewInt(int64(r.Intn(0xffffffff))), - R: h.Big(), - S: h.Big(), - }) - txs = append(txs, tx) - } else { - tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: randBig(r), - Nonce: r.Uint64(), - GasTipCap: randBig(r), - GasFeeCap: randBig(r), - Gas: r.Uint64(), - To: randAddrPtr(r), - Value: randBig(r), - Data: randBytes(r, r.Intn(300)), - AccessList: randAccessList(r, 300, 300), - V: big.NewInt(int64(r.Intn(0xffffffff))), - R: h.Big(), - S: h.Big(), - }) - txs = append(txs, tx) - } - } - mps := []MisbehaviourProof{} - for i := 0; i < mpsNum; i++ { - // MPs are serialized with RLP, so no need to test extensively - mps = append(mps, MisbehaviourProof{ - EventsDoublesign: &EventsDoublesign{ - Pair: [2]SignedEventLocator{SignedEventLocator{}, SignedEventLocator{}}, - }, - BlockVoteDoublesign: nil, - WrongBlockVote: nil, - EpochVoteDoublesign: nil, - WrongEpochVote: nil, - }) - } - bvs := LlrBlockVotes{} - if bvsNum > 0 { - bvs.Start = 1 + idx.Block(rand.Intn(1000)) - bvs.Epoch = 1 + idx.Epoch(rand.Intn(1000)) - } - for i := 0; i < bvsNum; i++ { - bvs.Votes = append(bvs.Votes, randHash(r)) - } - ers := LlrEpochVote{} - if ersNum { - ers.Epoch = 1 + idx.Epoch(rand.Intn(1000)) - ers.Vote = randHash(r) - } - - random.SetTxs(txs) - random.SetMisbehaviourProofs(mps) - random.SetEpochVote(ers) - random.SetBlockVotes(bvs) - random.SetPayloadHash(CalcPayloadHash(random)) - - parent := MutableEventPayload{} - parent.SetVersion(1) - parent.SetLamport(random.Lamport() - 500) - parent.SetEpoch(random.Epoch()) - random.SetParents(hash.Events{parent.Build().ID()}) - - return random.Build() -} diff --git a/evm/go-x1/inter/event_test.go b/evm/go-x1/inter/event_test.go deleted file mode 100644 index b61367e..0000000 --- a/evm/go-x1/inter/event_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package inter - -import ( - "encoding/hex" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestCalcMisbehaviourProofsHash(t *testing.T) { - v := []MisbehaviourProof{ - MisbehaviourProof{ - EventsDoublesign: &EventsDoublesign{ - Pair: [2]SignedEventLocator{ - test_signed_event_locator, - test_signed_event_locator, - }, - }, - }, - MisbehaviourProof{ - BlockVoteDoublesign: &BlockVoteDoublesign{ - Block: test_block_votes.Start, - Pair: [2]LlrSignedBlockVotes{ - test_llr_signed_block_votes, - test_llr_signed_block_votes, - }, - }, - }, - MisbehaviourProof{ - WrongBlockVote: &WrongBlockVote{ - Block: test_block_votes.Start, - Pals: [2]LlrSignedBlockVotes{ - test_llr_signed_block_votes, - test_llr_signed_block_votes, - }, - WrongEpoch: true, - }, - }, - MisbehaviourProof{ - EpochVoteDoublesign: &EpochVoteDoublesign{ - Pair: [2]LlrSignedEpochVote{ - test_llr_signed_epoch_vote, - test_llr_signed_epoch_vote, - }, - }, - }, - MisbehaviourProof{ - WrongEpochVote: &WrongEpochVote{ - Pals: [2]LlrSignedEpochVote{ - test_llr_signed_epoch_vote, - test_llr_signed_epoch_vote, - }, - }, - }, - } - - require.Equal(t, "85834ef7fc1d75d65832b1f9b45b43c4f5677811bb2d384208553d32ab49def1", hex.EncodeToString(CalcMisbehaviourProofsHash(v).Bytes())) -} diff --git a/evm/go-x1/inter/events.go b/evm/go-x1/inter/events.go deleted file mode 100644 index 3ede298..0000000 --- a/evm/go-x1/inter/events.go +++ /dev/null @@ -1,121 +0,0 @@ -package inter - -import ( - "bytes" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" -) - -// Events is a ordered slice of events. -type Events []*Event - -// String returns human readable representation. -func (ee Events) String() string { - return ee.Bases().String() -} - -// Add appends hash to the slice. -func (ee *Events) Add(e ...*Event) { - *ee = append(*ee, e...) -} - -func (ee Events) IDs() hash.Events { - res := make(hash.Events, 0, len(ee)) - for _, e := range ee { - res.Add(e.ID()) - } - return res -} - -func (ee Events) Bases() dag.Events { - res := make(dag.Events, 0, ee.Len()) - for _, e := range ee { - res = append(res, e) - } - return res -} - -func (ee Events) Interfaces() EventIs { - res := make(EventIs, 0, ee.Len()) - for _, e := range ee { - res = append(res, e) - } - return res -} - -func (ee Events) Len() int { return len(ee) } -func (ee Events) Swap(i, j int) { ee[i], ee[j] = ee[j], ee[i] } -func (ee Events) Less(i, j int) bool { - return bytes.Compare(ee[i].ID().Bytes(), ee[j].ID().Bytes()) < 0 -} - -// EventPayloads is a ordered slice of EventPayload. -type EventPayloads []*EventPayload - -// String returns human readable representation. -func (ee EventPayloads) String() string { - return ee.Bases().String() -} - -// Add appends hash to the slice. -func (ee *EventPayloads) Add(e ...*EventPayload) { - *ee = append(*ee, e...) -} - -func (ee EventPayloads) IDs() hash.Events { - res := make(hash.Events, 0, len(ee)) - for _, e := range ee { - res.Add(e.ID()) - } - return res -} - -func (ee EventPayloads) Bases() dag.Events { - res := make(dag.Events, 0, ee.Len()) - for _, e := range ee { - res = append(res, e) - } - return res -} - -func (ee EventPayloads) Len() int { return len(ee) } -func (ee EventPayloads) Swap(i, j int) { ee[i], ee[j] = ee[j], ee[i] } -func (ee EventPayloads) Less(i, j int) bool { - return bytes.Compare(ee[i].ID().Bytes(), ee[j].ID().Bytes()) < 0 -} - -// EventIs is a ordered slice of events. -type EventIs []EventI - -// String returns human readable representation. -func (ee EventIs) String() string { - return ee.Bases().String() -} - -// Add appends hash to the slice. -func (ee *EventIs) Add(e ...EventI) { - *ee = append(*ee, e...) -} - -func (ee EventIs) IDs() hash.Events { - res := make(hash.Events, 0, len(ee)) - for _, e := range ee { - res.Add(e.ID()) - } - return res -} - -func (ee EventIs) Bases() dag.Events { - res := make(dag.Events, 0, ee.Len()) - for _, e := range ee { - res = append(res, e) - } - return res -} - -func (ee EventIs) Len() int { return len(ee) } -func (ee EventIs) Swap(i, j int) { ee[i], ee[j] = ee[j], ee[i] } -func (ee EventIs) Less(i, j int) bool { - return bytes.Compare(ee[i].ID().Bytes(), ee[j].ID().Bytes()) < 0 -} diff --git a/evm/go-x1/inter/gas_power_left.go b/evm/go-x1/inter/gas_power_left.go deleted file mode 100644 index fc49404..0000000 --- a/evm/go-x1/inter/gas_power_left.go +++ /dev/null @@ -1,57 +0,0 @@ -package inter - -import "fmt" - -const ( - ShortTermGas = 0 - LongTermGas = 1 - GasPowerConfigs = 2 -) - -// GasPowerLeft is long-term gas power left and short-term gas power left -type GasPowerLeft struct { - Gas [GasPowerConfigs]uint64 -} - -// Add add to all gas power lefts -func (g GasPowerLeft) Add(diff uint64) { - for i := range g.Gas { - g.Gas[i] += diff - } -} - -// Min returns minimum within long-term gas power left and short-term gas power left -func (g GasPowerLeft) Min() uint64 { - min := g.Gas[0] - for _, gas := range g.Gas { - if min > gas { - min = gas - } - } - return min -} - -// Max returns maximum within long-term gas power left and short-term gas power left -func (g GasPowerLeft) Max() uint64 { - max := g.Gas[0] - for _, gas := range g.Gas { - if max < gas { - max = gas - } - } - return max -} - -// Sub subtracts from all gas power lefts -func (g GasPowerLeft) Sub(diff uint64) GasPowerLeft { - cp := g - for i := range cp.Gas { - cp.Gas[i] -= diff - } - return cp -} - -// String returns string representation. -func (g GasPowerLeft) String() string { - return fmt.Sprintf("{short=%d, long=%d}", g.Gas[ShortTermGas], g.Gas[LongTermGas]) -} diff --git a/evm/go-x1/inter/gas_power_left_test.go b/evm/go-x1/inter/gas_power_left_test.go deleted file mode 100644 index ecd91dd..0000000 --- a/evm/go-x1/inter/gas_power_left_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package inter - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" - "github.com/stretchr/testify/require" -) - -func TestRlp(t *testing.T) { - require := require.New(t) - v := GasPowerLeft{ - Gas: [2]uint64{0xBAADCAFE, 0xDEADBEEF}, - } - b, err := rlp.EncodeToBytes(v) - require.NoError(err) - require.Equal("cbca84baadcafe84deadbeef", common.Bytes2Hex(b)) -} diff --git a/evm/go-x1/inter/iblockproc/decided_state.go b/evm/go-x1/inter/iblockproc/decided_state.go deleted file mode 100644 index f4e4961..0000000 --- a/evm/go-x1/inter/iblockproc/decided_state.go +++ /dev/null @@ -1,154 +0,0 @@ -package iblockproc - -import ( - "crypto/sha256" - "math/big" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/lachesis" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera" -) - -type ValidatorBlockState struct { - LastEvent EventInfo - Uptime inter.Timestamp - LastOnlineTime inter.Timestamp - LastGasPowerLeft inter.GasPowerLeft - LastBlock idx.Block - DirtyGasRefund uint64 - Originated *big.Int -} - -type EventInfo struct { - ID hash.Event - GasPowerLeft inter.GasPowerLeft - Time inter.Timestamp -} - -type ValidatorEpochState struct { - GasRefund uint64 - PrevEpochEvent EventInfo -} - -type BlockCtx struct { - Idx idx.Block - Time inter.Timestamp - Atropos hash.Event -} - -type BlockState struct { - LastBlock BlockCtx - FinalizedStateRoot hash.Hash - - EpochGas uint64 - EpochCheaters lachesis.Cheaters - CheatersWritten uint32 - - ValidatorStates []ValidatorBlockState - NextValidatorProfiles ValidatorProfiles - - DirtyRules *opera.Rules `rlp:"nil"` // nil means that there's no changes compared to epoch rules - - AdvanceEpochs idx.Epoch -} - -func (bs BlockState) Copy() BlockState { - cp := bs - cp.EpochCheaters = make(lachesis.Cheaters, len(bs.EpochCheaters)) - copy(cp.EpochCheaters, bs.EpochCheaters) - cp.ValidatorStates = make([]ValidatorBlockState, len(bs.ValidatorStates)) - copy(cp.ValidatorStates, bs.ValidatorStates) - for i := range cp.ValidatorStates { - cp.ValidatorStates[i].Originated = new(big.Int).Set(cp.ValidatorStates[i].Originated) - } - cp.NextValidatorProfiles = bs.NextValidatorProfiles.Copy() - if bs.DirtyRules != nil { - rules := bs.DirtyRules.Copy() - cp.DirtyRules = &rules - } - return cp -} - -func (bs *BlockState) GetValidatorState(id idx.ValidatorID, validators *pos.Validators) *ValidatorBlockState { - validatorIdx := validators.GetIdx(id) - return &bs.ValidatorStates[validatorIdx] -} - -func (bs BlockState) Hash() hash.Hash { - hasher := sha256.New() - err := rlp.Encode(hasher, &bs) - if err != nil { - panic("can't hash: " + err.Error()) - } - return hash.BytesToHash(hasher.Sum(nil)) -} - -type EpochStateV1 struct { - Epoch idx.Epoch - EpochStart inter.Timestamp - PrevEpochStart inter.Timestamp - - EpochStateRoot hash.Hash - - Validators *pos.Validators - ValidatorStates []ValidatorEpochState - ValidatorProfiles ValidatorProfiles - - Rules opera.Rules -} - -type EpochState EpochStateV1 - -func (es *EpochState) GetValidatorState(id idx.ValidatorID, validators *pos.Validators) *ValidatorEpochState { - validatorIdx := validators.GetIdx(id) - return &es.ValidatorStates[validatorIdx] -} - -func (es EpochState) Duration() inter.Timestamp { - return es.EpochStart - es.PrevEpochStart -} - -func (es EpochState) Hash() hash.Hash { - var hashed interface{} - if es.Rules.Upgrades.London { - hashed = &es - } else { - es0 := EpochStateV0{ - Epoch: es.Epoch, - EpochStart: es.EpochStart, - PrevEpochStart: es.PrevEpochStart, - EpochStateRoot: es.EpochStateRoot, - Validators: es.Validators, - ValidatorStates: make([]ValidatorEpochStateV0, len(es.ValidatorStates)), - ValidatorProfiles: es.ValidatorProfiles, - Rules: es.Rules, - } - for i, v := range es.ValidatorStates { - es0.ValidatorStates[i].GasRefund = v.GasRefund - es0.ValidatorStates[i].PrevEpochEvent = v.PrevEpochEvent.ID - } - hashed = &es0 - } - hasher := sha256.New() - err := rlp.Encode(hasher, hashed) - if err != nil { - panic("can't hash: " + err.Error()) - } - return hash.BytesToHash(hasher.Sum(nil)) -} - -func (es EpochState) Copy() EpochState { - cp := es - cp.ValidatorStates = make([]ValidatorEpochState, len(es.ValidatorStates)) - copy(cp.ValidatorStates, es.ValidatorStates) - cp.ValidatorProfiles = es.ValidatorProfiles.Copy() - if es.Rules != (opera.Rules{}) { - cp.Rules = es.Rules.Copy() - } - return cp -} diff --git a/evm/go-x1/inter/iblockproc/legacy.go b/evm/go-x1/inter/iblockproc/legacy.go deleted file mode 100644 index bf18d23..0000000 --- a/evm/go-x1/inter/iblockproc/legacy.go +++ /dev/null @@ -1,29 +0,0 @@ -package iblockproc - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera" -) - -type ValidatorEpochStateV0 struct { - GasRefund uint64 - PrevEpochEvent hash.Event -} - -type EpochStateV0 struct { - Epoch idx.Epoch - EpochStart inter.Timestamp - PrevEpochStart inter.Timestamp - - EpochStateRoot hash.Hash - - Validators *pos.Validators - ValidatorStates []ValidatorEpochStateV0 - ValidatorProfiles ValidatorProfiles - - Rules opera.Rules -} diff --git a/evm/go-x1/inter/iblockproc/profiles.go b/evm/go-x1/inter/iblockproc/profiles.go deleted file mode 100644 index cb6d5f5..0000000 --- a/evm/go-x1/inter/iblockproc/profiles.go +++ /dev/null @@ -1,63 +0,0 @@ -package iblockproc - -import ( - "io" - "math/big" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/inter/drivertype" -) - -type ValidatorProfiles map[idx.ValidatorID]drivertype.Validator - -func (vv ValidatorProfiles) Copy() ValidatorProfiles { - cp := make(ValidatorProfiles, len(vv)) - for k, v := range vv { - cpv := v - cpv.Weight = new(big.Int).Set(cpv.Weight) - cpv.PubKey = cpv.PubKey.Copy() - cp[k] = cpv - } - return cp -} - -func (vv ValidatorProfiles) SortedArray() []drivertype.ValidatorAndID { - builder := pos.NewBigBuilder() - for id, profile := range vv { - builder.Set(id, profile.Weight) - } - validators := builder.Build() - sortedIds := validators.SortedIDs() - arr := make([]drivertype.ValidatorAndID, validators.Len()) - for i, id := range sortedIds { - arr[i] = drivertype.ValidatorAndID{ - ValidatorID: id, - Validator: vv[id], - } - } - return arr -} - -// EncodeRLP is for RLP serialization. -func (vv ValidatorProfiles) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, vv.SortedArray()) -} - -// DecodeRLP is for RLP deserialization. -func (vv *ValidatorProfiles) DecodeRLP(s *rlp.Stream) error { - var arr []drivertype.ValidatorAndID - if err := s.Decode(&arr); err != nil { - return err - } - - *vv = make(ValidatorProfiles, len(arr)) - - for _, it := range arr { - (*vv)[it.ValidatorID] = it.Validator - } - - return nil -} diff --git a/evm/go-x1/inter/ibr/inter_block_records.go b/evm/go-x1/inter/ibr/inter_block_records.go deleted file mode 100644 index 3d2fac8..0000000 --- a/evm/go-x1/inter/ibr/inter_block_records.go +++ /dev/null @@ -1,48 +0,0 @@ -package ibr - -import ( - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/inter" -) - -type LlrBlockVote struct { - Atropos hash.Event - Root hash.Hash - TxHash hash.Hash - ReceiptsHash hash.Hash - Time inter.Timestamp - GasUsed uint64 -} - -type LlrFullBlockRecord struct { - Atropos hash.Event - Root hash.Hash - Txs types.Transactions - Receipts []*types.ReceiptForStorage - Time inter.Timestamp - GasUsed uint64 -} - -type LlrIdxFullBlockRecord struct { - LlrFullBlockRecord - Idx idx.Block -} - -func (bv LlrBlockVote) Hash() hash.Hash { - return hash.Of(bv.Atropos.Bytes(), bv.Root.Bytes(), bv.TxHash.Bytes(), bv.ReceiptsHash.Bytes(), bv.Time.Bytes(), bigendian.Uint64ToBytes(bv.GasUsed)) -} - -func (br LlrFullBlockRecord) Hash() hash.Hash { - return LlrBlockVote{ - Atropos: br.Atropos, - Root: br.Root, - TxHash: inter.CalcTxHash(br.Txs), - ReceiptsHash: inter.CalcReceiptsHash(br.Receipts), - Time: br.Time, - GasUsed: br.GasUsed, - }.Hash() -} diff --git a/evm/go-x1/inter/iep/inter_epoch_packs.go b/evm/go-x1/inter/iep/inter_epoch_packs.go deleted file mode 100644 index 59196df..0000000 --- a/evm/go-x1/inter/iep/inter_epoch_packs.go +++ /dev/null @@ -1,11 +0,0 @@ -package iep - -import ( - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/inter/ier" -) - -type LlrEpochPack struct { - Votes []inter.LlrSignedEpochVote - Record ier.LlrIdxFullEpochRecord -} diff --git a/evm/go-x1/inter/ier/inter_epoch_records.go b/evm/go-x1/inter/ier/inter_epoch_records.go deleted file mode 100644 index 1395867..0000000 --- a/evm/go-x1/inter/ier/inter_epoch_records.go +++ /dev/null @@ -1,22 +0,0 @@ -package ier - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - - "github.com/Fantom-foundation/go-opera/inter/iblockproc" -) - -type LlrFullEpochRecord struct { - BlockState iblockproc.BlockState - EpochState iblockproc.EpochState -} - -type LlrIdxFullEpochRecord struct { - LlrFullEpochRecord - Idx idx.Epoch -} - -func (er LlrFullEpochRecord) Hash() hash.Hash { - return hash.Of(er.BlockState.Hash().Bytes(), er.EpochState.Hash().Bytes()) -} diff --git a/evm/go-x1/inter/inter_llr.go b/evm/go-x1/inter/inter_llr.go deleted file mode 100644 index 0089c12..0000000 --- a/evm/go-x1/inter/inter_llr.go +++ /dev/null @@ -1,94 +0,0 @@ -package inter - -import ( - "crypto/sha256" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -type LlrBlockVotes struct { - Start idx.Block - Epoch idx.Epoch - Votes []hash.Hash -} - -func (bvs LlrBlockVotes) LastBlock() idx.Block { - return bvs.Start + idx.Block(len(bvs.Votes)) - 1 -} - -type LlrEpochVote struct { - Epoch idx.Epoch - Vote hash.Hash -} - -type LlrSignedBlockVotes struct { - Signed SignedEventLocator - TxsAndMisbehaviourProofsHash hash.Hash - EpochVoteHash hash.Hash - Val LlrBlockVotes -} - -type LlrSignedEpochVote struct { - Signed SignedEventLocator - TxsAndMisbehaviourProofsHash hash.Hash - BlockVotesHash hash.Hash - Val LlrEpochVote -} - -func AsSignedBlockVotes(e EventPayloadI) LlrSignedBlockVotes { - return LlrSignedBlockVotes{ - Signed: AsSignedEventLocator(e), - TxsAndMisbehaviourProofsHash: hash.Of(CalcTxHash(e.Txs()).Bytes(), CalcMisbehaviourProofsHash(e.MisbehaviourProofs()).Bytes()), - EpochVoteHash: e.EpochVote().Hash(), - Val: e.BlockVotes(), - } -} - -func AsSignedEpochVote(e EventPayloadI) LlrSignedEpochVote { - return LlrSignedEpochVote{ - Signed: AsSignedEventLocator(e), - TxsAndMisbehaviourProofsHash: hash.Of(CalcTxHash(e.Txs()).Bytes(), CalcMisbehaviourProofsHash(e.MisbehaviourProofs()).Bytes()), - BlockVotesHash: e.BlockVotes().Hash(), - Val: e.EpochVote(), - } -} - -func (r SignedEventLocator) Size() uint64 { - return uint64(len(r.Sig)) + 3*32 + 4*4 -} - -func (bvs LlrSignedBlockVotes) Size() uint64 { - return bvs.Signed.Size() + uint64(len(bvs.Val.Votes))*32 + 32*2 + 8 + 4 -} - -func (ers LlrEpochVote) Hash() hash.Hash { - hasher := sha256.New() - hasher.Write(ers.Epoch.Bytes()) - hasher.Write(ers.Vote.Bytes()) - return hash.BytesToHash(hasher.Sum(nil)) -} - -func (bvs LlrBlockVotes) Hash() hash.Hash { - hasher := sha256.New() - hasher.Write(bvs.Start.Bytes()) - hasher.Write(bvs.Epoch.Bytes()) - hasher.Write(bigendian.Uint32ToBytes(uint32(len(bvs.Votes)))) - for _, bv := range bvs.Votes { - hasher.Write(bv.Bytes()) - } - return hash.BytesToHash(hasher.Sum(nil)) -} - -func (bvs LlrSignedBlockVotes) CalcPayloadHash() hash.Hash { - return hash.Of(bvs.TxsAndMisbehaviourProofsHash.Bytes(), hash.Of(bvs.EpochVoteHash.Bytes(), bvs.Val.Hash().Bytes()).Bytes()) -} - -func (ev LlrSignedEpochVote) CalcPayloadHash() hash.Hash { - return hash.Of(ev.TxsAndMisbehaviourProofsHash.Bytes(), hash.Of(ev.Val.Hash().Bytes(), ev.BlockVotesHash.Bytes()).Bytes()) -} - -func (ev LlrSignedEpochVote) Size() uint64 { - return ev.Signed.Size() + 32 + 32*2 + 4 + 4 -} diff --git a/evm/go-x1/inter/inter_llr_test.go b/evm/go-x1/inter/inter_llr_test.go deleted file mode 100644 index 4a9af6b..0000000 --- a/evm/go-x1/inter/inter_llr_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package inter - -import ( - "encoding/hex" - "testing" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/stretchr/testify/require" -) - -var test_block_votes = LlrBlockVotes{ - Start: 9000, - Epoch: 342, - Votes: []hash.Hash{ - hash.Of(nil), - }, -} -var test_signed_event_locator = SignedEventLocator{ - Locator: EventLocator{ - BaseHash: hash.Of(nil), - NetForkID: 1, - Epoch: 42, - Seq: 9_000_000, - Lamport: 142, - Creator: 242, - PayloadHash: hash.Of(nil), - }, - Sig: [64]byte{}, -} -var test_txs_and_misbehaviour_proofs_hash = hash.Of(nil) -var test_epoch_vote_hash = hash.Of(nil) -var test_block_votes_hash = hash.Of(nil) - -var test_llr_signed_block_votes = LlrSignedBlockVotes{ - Signed: test_signed_event_locator, - TxsAndMisbehaviourProofsHash: test_txs_and_misbehaviour_proofs_hash, - EpochVoteHash: test_epoch_vote_hash, - Val: test_block_votes, -} -var test_llr_signed_epoch_vote = LlrSignedEpochVote{ - Signed: test_signed_event_locator, - TxsAndMisbehaviourProofsHash: test_txs_and_misbehaviour_proofs_hash, - BlockVotesHash: test_block_votes_hash, - Val: LlrEpochVote{ - Epoch: test_signed_event_locator.Locator.Epoch, - Vote: test_epoch_vote_hash, - }, -} - -func TestLlrBlockVotesHashing(t *testing.T) { - require.Equal(t, "7db20066868c07236a5f5641eac6a1ddb5cd1dc1602252a3672758056b4562a8", hex.EncodeToString(test_block_votes.Hash().Bytes())) -} - -func TestLlrSignedBlockVotesHashing(t *testing.T) { - require.Equal(t, "26b5c58d72b48f2ce40f5e18df4dda66f644839d00611b9a7812e8f9f708f143", hex.EncodeToString(test_llr_signed_block_votes.CalcPayloadHash().Bytes())) -} - -func TestLlrSignedEpochVoteHashing(t *testing.T) { - require.Equal(t, "e6c5f9d9e45f04b286c8361d8b5851f7ee16538f408ad86afa4d2b2612a10a75", hex.EncodeToString(test_llr_signed_epoch_vote.CalcPayloadHash().Bytes())) -} diff --git a/evm/go-x1/inter/inter_mps.go b/evm/go-x1/inter/inter_mps.go deleted file mode 100644 index 88fe761..0000000 --- a/evm/go-x1/inter/inter_mps.go +++ /dev/null @@ -1,55 +0,0 @@ -package inter - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -const ( - // MinAccomplicesForProof defines how many validators must have signed the same wrong vote. - // Otherwise, wrong-signer is not liable as a protection against singular software/hardware failures - MinAccomplicesForProof = 2 -) - -type EventsDoublesign struct { - Pair [2]SignedEventLocator -} - -type BlockVoteDoublesign struct { - Block idx.Block - Pair [2]LlrSignedBlockVotes -} - -func (p BlockVoteDoublesign) GetVote(i int) hash.Hash { - return p.Pair[i].Val.Votes[p.Block-p.Pair[i].Val.Start] -} - -type WrongBlockVote struct { - Block idx.Block - Pals [MinAccomplicesForProof]LlrSignedBlockVotes - WrongEpoch bool -} - -func (p WrongBlockVote) GetVote(i int) hash.Hash { - return p.Pals[i].Val.Votes[p.Block-p.Pals[i].Val.Start] -} - -type EpochVoteDoublesign struct { - Pair [2]LlrSignedEpochVote -} - -type WrongEpochVote struct { - Pals [MinAccomplicesForProof]LlrSignedEpochVote -} - -type MisbehaviourProof struct { - EventsDoublesign *EventsDoublesign `rlp:"nil"` - - BlockVoteDoublesign *BlockVoteDoublesign `rlp:"nil"` - - WrongBlockVote *WrongBlockVote `rlp:"nil"` - - EpochVoteDoublesign *EpochVoteDoublesign `rlp:"nil"` - - WrongEpochVote *WrongEpochVote `rlp:"nil"` -} diff --git a/evm/go-x1/inter/signature.go b/evm/go-x1/inter/signature.go deleted file mode 100644 index 6a5123c..0000000 --- a/evm/go-x1/inter/signature.go +++ /dev/null @@ -1,18 +0,0 @@ -package inter - -const SigSize = 64 - -// Signature is a secp256k1 signature in R|S format -type Signature [SigSize]byte - -func (s Signature) Bytes() []byte { - return s[:] -} - -func BytesToSignature(b []byte) (sig Signature) { - if len(b) != SigSize { - panic("invalid signature length") - } - copy(sig[:], b) - return sig -} diff --git a/evm/go-x1/inter/time.go b/evm/go-x1/inter/time.go deleted file mode 100644 index 6a1bbbc..0000000 --- a/evm/go-x1/inter/time.go +++ /dev/null @@ -1,45 +0,0 @@ -package inter - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" -) - -type ( - // Timestamp is a UNIX nanoseconds timestamp - Timestamp uint64 -) - -// Bytes gets the byte representation of the index. -func (t Timestamp) Bytes() []byte { - return bigendian.Uint64ToBytes(uint64(t)) -} - -// BytesToTimestamp converts bytes to timestamp. -func BytesToTimestamp(b []byte) Timestamp { - return Timestamp(bigendian.BytesToUint64(b)) -} - -func FromUnix(t int64) Timestamp { - return Timestamp(int64(t) * int64(time.Second)) -} - -// Unix returns t as a Unix time, the number of seconds elapsed -// since January 1, 1970 UTC. The result does not depend on the -// location associated with t. -func (t Timestamp) Unix() int64 { - return int64(t) / int64(time.Second) -} - -func (t Timestamp) Time() time.Time { - return time.Unix(int64(t)/int64(time.Second), int64(t)%int64(time.Second)) -} - -// MaxTimestamp return max value. -func MaxTimestamp(x, y Timestamp) Timestamp { - if x > y { - return x - } - return y -} diff --git a/evm/go-x1/inter/transaction_serializer.go b/evm/go-x1/inter/transaction_serializer.go deleted file mode 100644 index ad7a3cd..0000000 --- a/evm/go-x1/inter/transaction_serializer.go +++ /dev/null @@ -1,166 +0,0 @@ -package inter - -import ( - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/utils/cser" -) - -var ErrUnknownTxType = errors.New("unknown tx type") - -func encodeSig(r, s *big.Int) (sig [64]byte) { - copy(sig[0:], cser.PaddedBytes(r.Bytes(), 32)[:32]) - copy(sig[32:], cser.PaddedBytes(s.Bytes(), 32)[:32]) - return sig -} - -func decodeSig(sig [64]byte) (r, s *big.Int) { - r = new(big.Int).SetBytes(sig[:32]) - s = new(big.Int).SetBytes(sig[32:64]) - return -} - -func TransactionMarshalCSER(w *cser.Writer, tx *types.Transaction) error { - if tx.Type() != types.LegacyTxType && tx.Type() != types.AccessListTxType && tx.Type() != types.DynamicFeeTxType { - return ErrUnknownTxType - } - if tx.Type() != types.LegacyTxType { - // marker of a non-standard tx - w.BitsW.Write(6, 0) - // tx type - w.U8(tx.Type()) - } else if tx.Gas() <= 0xff { - return errors.New("cannot serialize legacy tx with gasLimit <= 256") - } - w.U64(tx.Nonce()) - w.U64(tx.Gas()) - if tx.Type() == types.DynamicFeeTxType { - w.BigInt(tx.GasTipCap()) - w.BigInt(tx.GasFeeCap()) - } else { - w.BigInt(tx.GasPrice()) - } - w.BigInt(tx.Value()) - w.Bool(tx.To() != nil) - if tx.To() != nil { - w.FixedBytes(tx.To().Bytes()) - } - w.SliceBytes(tx.Data()) - v, r, s := tx.RawSignatureValues() - w.BigInt(v) - sig := encodeSig(r, s) - w.FixedBytes(sig[:]) - if tx.Type() == types.AccessListTxType || tx.Type() == types.DynamicFeeTxType { - w.BigInt(tx.ChainId()) - w.U32(uint32(len(tx.AccessList()))) - for _, tuple := range tx.AccessList() { - w.FixedBytes(tuple.Address.Bytes()) - w.U32(uint32(len(tuple.StorageKeys))) - for _, h := range tuple.StorageKeys { - w.FixedBytes(h.Bytes()) - } - } - } - return nil -} - -func TransactionUnmarshalCSER(r *cser.Reader) (*types.Transaction, error) { - txType := uint8(types.LegacyTxType) - if r.BitsR.View(6) == 0 { - r.BitsR.Read(6) - txType = r.U8() - } - - nonce := r.U64() - gasLimit := r.U64() - var gasPrice *big.Int - var gasTipCap *big.Int - var gasFeeCap *big.Int - if txType == types.DynamicFeeTxType { - gasTipCap = r.BigInt() - gasFeeCap = r.BigInt() - } else { - gasPrice = r.BigInt() - } - amount := r.BigInt() - toExists := r.Bool() - var to *common.Address - if toExists { - var _to common.Address - r.FixedBytes(_to[:]) - to = &_to - } - data := r.SliceBytes(ProtocolMaxMsgSize) - // sig - v := r.BigInt() - var sig [64]byte - r.FixedBytes(sig[:]) - _r, s := decodeSig(sig) - - if txType == types.LegacyTxType { - return types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasPrice, - Gas: gasLimit, - To: to, - Value: amount, - Data: data, - V: v, - R: _r, - S: s, - }), nil - } else if txType == types.AccessListTxType || txType == types.DynamicFeeTxType { - chainID := r.BigInt() - accessListLen := r.U32() - if accessListLen > ProtocolMaxMsgSize/24 { - return nil, cser.ErrTooLargeAlloc - } - accessList := make(types.AccessList, accessListLen) - for i := range accessList { - r.FixedBytes(accessList[i].Address[:]) - keysLen := r.U32() - if keysLen > ProtocolMaxMsgSize/32 { - return nil, cser.ErrTooLargeAlloc - } - accessList[i].StorageKeys = make([]common.Hash, keysLen) - for j := range accessList[i].StorageKeys { - r.FixedBytes(accessList[i].StorageKeys[j][:]) - } - } - if txType == types.AccessListTxType { - return types.NewTx(&types.AccessListTx{ - ChainID: chainID, - Nonce: nonce, - GasPrice: gasPrice, - Gas: gasLimit, - To: to, - Value: amount, - Data: data, - AccessList: accessList, - V: v, - R: _r, - S: s, - }), nil - } else { - return types.NewTx(&types.DynamicFeeTx{ - ChainID: chainID, - Nonce: nonce, - GasTipCap: gasTipCap, - GasFeeCap: gasFeeCap, - Gas: gasLimit, - To: to, - Value: amount, - Data: data, - AccessList: accessList, - V: v, - R: _r, - S: s, - }), nil - } - } - return nil, ErrUnknownTxType -} diff --git a/evm/go-x1/inter/transaction_serializer_test.go b/evm/go-x1/inter/transaction_serializer_test.go deleted file mode 100644 index 97b9a1a..0000000 --- a/evm/go-x1/inter/transaction_serializer_test.go +++ /dev/null @@ -1,144 +0,0 @@ -package inter - -import ( - "encoding/hex" - "math/big" - "testing" - - "github.com/Fantom-foundation/go-opera/utils/cser" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" -) - -func TestSerializeLegacyTx(t *testing.T) { - require := require.New(t) - - addr := common.HexToAddress("727fc6a68321b754475c668a6abfb6e9e71c169a") - value := big.NewInt(10) - value = value.Mul(value, big.NewInt(1_000_000_000)) - value = value.Mul(value, big.NewInt(1_000_000_000)) - - data, _ := hex.DecodeString("a9059cbb000000000213ed0f886efd100b67c7e4ec0a85a7d20dc971600000000000000000000015af1d78b58c4000") - - r := new(big.Int) - r.SetString("be67e0a07db67da8d446f76add590e54b6e92cb6b8f9835aeb67540579a27717", 16) - - s := new(big.Int) - s.SetString("2d690516512020171c1ec870f6ff45398cc8609250326be89915fb538e7bd718", 16) - - v := types.NewTx(&types.LegacyTx{ - Nonce: 12, - GasPrice: big.NewInt(20_000_000_000), - Gas: 21_000, - To: &addr, - Value: value, - Data: data, - V: big.NewInt(40), - R: r, - S: s, - }) - - encoded, err := cser.MarshalBinaryAdapter(func(w *cser.Writer) error { - return TransactionMarshalCSER(w, v) - }) - require.NoError(err) - require.Equal("0c08520504a817c800088ac7230489e80000727fc6a68321b754475c668a6abfb6e9e71c169a2fa9059cbb000000000213ed0f886efd100b67c7e4ec0a85a7d20dc971600000000000000000000015af1d78b58c40000128be67e0a07db67da8d446f76add590e54b6e92cb6b8f9835aeb67540579a277172d690516512020171c1ec870f6ff45398cc8609250326be89915fb538e7bd71848320183", hex.EncodeToString(encoded)) -} - -func TestSerializeAccessListTx(t *testing.T) { - require := require.New(t) - - addr := common.HexToAddress("811a752c8cd697e3cb27279c330ed1ada745a8d7") - value := big.NewInt(2) - value = value.Mul(value, big.NewInt(1_000_000_000)) - value = value.Mul(value, big.NewInt(1_000_000_000)) - - data, _ := hex.DecodeString("6ebaf477f83e051589c1188bcc6ddccd") - - r := new(big.Int) - r.SetString("36b241b061a36a32ab7fe86c7aa9eb592dd59018cd0443adc0903590c16b02b0", 16) - - s := new(big.Int) - s.SetString("5edcc541b4741c5cc6dd347c5ed9577ef293a62787b4510465fadbfe39ee4094", 16) - - v := types.NewTx(&types.AccessListTx{ - ChainID: big.NewInt(5), - Nonce: 7, - GasPrice: big.NewInt(30_000_000_000), - Gas: 5_748_100, - To: &addr, - Value: value, - Data: data, - AccessList: []types.AccessTuple{ - types.AccessTuple{ - Address: common.HexToAddress("de0b295669a9fd93d5f28d9ec85e40f4cb697bae"), - StorageKeys: []common.Hash{ - common.HexToHash("0000000000000000000000000000000000000000000000000000000000000003"), - common.HexToHash("0000000000000000000000000000000000000000000000000000000000000007"), - }, - }, - types.AccessTuple{ - Address: common.HexToAddress("bb9bc244d798123fde783fcc1c72d3bb8c189413"), - }, - }, - V: big.NewInt(45), - R: r, - S: s, - }) - - encoded, err := cser.MarshalBinaryAdapter(func(w *cser.Writer) error { - return TransactionMarshalCSER(w, v) - }) - require.NoError(err) - require.Equal("010784b5570506fc23ac00081bc16d674ec80000811a752c8cd697e3cb27279c330ed1ada745a8d7106ebaf477f83e051589c1188bcc6ddccd012d36b241b061a36a32ab7fe86c7aa9eb592dd59018cd0443adc0903590c16b02b05edcc541b4741c5cc6dd347c5ed9577ef293a62787b4510465fadbfe39ee4094010502de0b295669a9fd93d5f28d9ec85e40f4cb697bae0200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000007bb9bc244d798123fde783fcc1c72d3bb8c1894130000944c020085", hex.EncodeToString(encoded)) -} - -func TestSerializeDynamicFeeTx(t *testing.T) { - require := require.New(t) - - addr := common.HexToAddress("811a752c8cd697e3cb27279c330ed1ada745a8d7") - value := big.NewInt(2) - value = value.Mul(value, big.NewInt(1_000_000_000)) - value = value.Mul(value, big.NewInt(1_000_000_000)) - - data, _ := hex.DecodeString("6ebaf477f83e051589c1188bcc6ddccd") - - r := new(big.Int) - r.SetString("36b241b061a36a32ab7fe86c7aa9eb592dd59018cd0443adc0903590c16b02b0", 16) - - s := new(big.Int) - s.SetString("5edcc541b4741c5cc6dd347c5ed9577ef293a62787b4510465fadbfe39ee4094", 16) - - v := types.NewTx(&types.DynamicFeeTx{ - ChainID: big.NewInt(5), - Nonce: 7, - GasTipCap: big.NewInt(10_000_000_000), - GasFeeCap: big.NewInt(30_000_000_000), - Gas: 5_748_100, - To: &addr, - Value: value, - Data: data, - AccessList: []types.AccessTuple{ - types.AccessTuple{ - Address: common.HexToAddress("de0b295669a9fd93d5f28d9ec85e40f4cb697bae"), - StorageKeys: []common.Hash{ - common.HexToHash("0000000000000000000000000000000000000000000000000000000000000003"), - common.HexToHash("0000000000000000000000000000000000000000000000000000000000000007"), - }, - }, - types.AccessTuple{ - Address: common.HexToAddress("bb9bc244d798123fde783fcc1c72d3bb8c189413"), - }, - }, - V: big.NewInt(45), - R: r, - S: s, - }) - - encoded, err := cser.MarshalBinaryAdapter(func(w *cser.Writer) error { - return TransactionMarshalCSER(w, v) - }) - require.NoError(err) - require.Equal("020784b5570502540be4000506fc23ac00081bc16d674ec80000811a752c8cd697e3cb27279c330ed1ada745a8d7106ebaf477f83e051589c1188bcc6ddccd012d36b241b061a36a32ab7fe86c7aa9eb592dd59018cd0443adc0903590c16b02b05edcc541b4741c5cc6dd347c5ed9577ef293a62787b4510465fadbfe39ee4094010502de0b295669a9fd93d5f28d9ec85e40f4cb697bae0200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000007bb9bc244d798123fde783fcc1c72d3bb8c18941300009464120085", hex.EncodeToString(encoded)) -} diff --git a/evm/go-x1/inter/validatorpk/pubkey.go b/evm/go-x1/inter/validatorpk/pubkey.go deleted file mode 100644 index 1b82a8f..0000000 --- a/evm/go-x1/inter/validatorpk/pubkey.go +++ /dev/null @@ -1,66 +0,0 @@ -package validatorpk - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" -) - -const ( - FakePassword = "fakepassword" -) - -type PubKey struct { - Type uint8 - Raw []byte -} - -var Types = struct { - Secp256k1 uint8 -}{ - Secp256k1: 0xc0, -} - -func (pk PubKey) Empty() bool { - return len(pk.Raw) == 0 && pk.Type == 0 -} - -func (pk PubKey) String() string { - return "0x" + common.Bytes2Hex(pk.Bytes()) -} - -func (pk PubKey) Bytes() []byte { - return append([]byte{pk.Type}, pk.Raw...) -} - -func (pk PubKey) Copy() PubKey { - return PubKey{ - Type: pk.Type, - Raw: common.CopyBytes(pk.Raw), - } -} - -func FromString(str string) (PubKey, error) { - return FromBytes(common.FromHex(str)) -} - -func FromBytes(b []byte) (PubKey, error) { - if len(b) == 0 { - return PubKey{}, errors.New("empty pubkey") - } - return PubKey{b[0], b[1:]}, nil -} - -// MarshalText returns the hex representation of a. -func (pk *PubKey) MarshalText() ([]byte, error) { - return []byte(pk.String()), nil -} - -// UnmarshalText parses a hash in hex syntax. -func (pk *PubKey) UnmarshalText(input []byte) error { - res, err := FromString(string(input)) - if err != nil { - return err - } - *pk = res - return nil -} diff --git a/evm/go-x1/inter/validatorpk/pubkey_test.go b/evm/go-x1/inter/validatorpk/pubkey_test.go deleted file mode 100644 index 93fa9f1..0000000 --- a/evm/go-x1/inter/validatorpk/pubkey_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package validatorpk - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" - "github.com/stretchr/testify/require" -) - -func TestFromString(t *testing.T) { - require := require.New(t) - exp := PubKey{ - Type: Types.Secp256k1, - Raw: common.FromHex("45b86101f804f3f4f2012ef31fff807e87de579a3faa7947d1b487a810e35dc2c3b6071ac465046634b5f4a8e09bf8e1f2e7eccb699356b9e6fd496ca4b1677d1"), - } - { - got, err := FromString("c0045b86101f804f3f4f2012ef31fff807e87de579a3faa7947d1b487a810e35dc2c3b6071ac465046634b5f4a8e09bf8e1f2e7eccb699356b9e6fd496ca4b1677d1") - require.NoError(err) - require.Equal(exp, got) - } - { - got, err := FromString("0xc0045b86101f804f3f4f2012ef31fff807e87de579a3faa7947d1b487a810e35dc2c3b6071ac465046634b5f4a8e09bf8e1f2e7eccb699356b9e6fd496ca4b1677d1") - require.NoError(err) - require.Equal(exp, got) - } - { - _, err := FromString("") - require.Error(err) - } - { - _, err := FromString("0x") - require.Error(err) - } - { - _, err := FromString("-") - require.Error(err) - } -} - -func TestString(t *testing.T) { - require := require.New(t) - pk := PubKey{ - Type: Types.Secp256k1, - Raw: common.FromHex("45b86101f804f3f4f2012ef31fff807e87de579a3faa7947d1b487a810e35dc2c3b6071ac465046634b5f4a8e09bf8e1f2e7eccb699356b9e6fd496ca4b1677d1"), - } - require.Equal("0xc0045b86101f804f3f4f2012ef31fff807e87de579a3faa7947d1b487a810e35dc2c3b6071ac465046634b5f4a8e09bf8e1f2e7eccb699356b9e6fd496ca4b1677d1", pk.String()) -} - -func TestRlp(t *testing.T) { - require := require.New(t) - v := PubKey{ - Type: Types.Secp256k1, - Raw: common.FromHex("45b86101f804f3f4f2012ef31fff807e87de579a3faa7947d1b487a810e35dc2c3b6071ac465046634b5f4a8e09bf8e1f2e7eccb699356b9e6fd496ca4b1677d1"), - } - b, err := rlp.EncodeToBytes(v) - require.NoError(err) - require.Equal("f84581c0b841045b86101f804f3f4f2012ef31fff807e87de579a3faa7947d1b487a810e35dc2c3b6071ac465046634b5f4a8e09bf8e1f2e7eccb699356b9e6fd496ca4b1677d1", common.Bytes2Hex(b)) -} diff --git a/evm/go-x1/logger/instance.go b/evm/go-x1/logger/instance.go deleted file mode 100644 index 145f774..0000000 --- a/evm/go-x1/logger/instance.go +++ /dev/null @@ -1,20 +0,0 @@ -package logger - -import ( - "github.com/ethereum/go-ethereum/log" -) - -type Instance struct { - Log log.Logger -} - -func New(name ...string) Instance { - if len(name) == 0 { - return Instance{ - Log: log.New(), - } - } - return Instance{ - Log: log.New("module", name[0]), - } -} diff --git a/evm/go-x1/logger/logger.go b/evm/go-x1/logger/logger.go deleted file mode 100644 index 1b20913..0000000 --- a/evm/go-x1/logger/logger.go +++ /dev/null @@ -1,49 +0,0 @@ -package logger - -import ( - "github.com/ethereum/go-ethereum/log" - "github.com/evalphobia/logrus_sentry" -) - -// init with defaults. -func init() { - log.Root().SetHandler( - log.CallerStackHandler("%v", log.StdoutHandler)) -} - -// SetDSN appends sentry hook to log root handler. -func SetDSN(value string) { - // If DSN is empty, we don't create new hook. - // Otherwise we'll the same error message for each new log. - if value == "" { - log.Warn("Sentry client DSN is empty") - return - } - - // TODO: find or make sentry log.Handler without logrus. - sentry, err := logrus_sentry.NewSentryHook(value, nil) - if err != nil { - log.Warn("Probably Sentry host is not running", "err", err) - return - } - - log.Root().SetHandler( - log.MultiHandler( - log.Root().GetHandler(), - LogrusHandler(sentry), - )) -} - -// SetLevel sets level filter on log root handler. -// So it should be called last. -func SetLevel(l string) { - lvl, err := log.LvlFromString(l) - if err != nil { - panic(err) - } - - log.Root().SetHandler( - log.LvlFilterHandler( - lvl, - log.Root().GetHandler())) -} diff --git a/evm/go-x1/logger/logrus.go b/evm/go-x1/logger/logrus.go deleted file mode 100644 index c86915f..0000000 --- a/evm/go-x1/logger/logrus.go +++ /dev/null @@ -1,30 +0,0 @@ -package logger - -import ( - "github.com/ethereum/go-ethereum/log" - "github.com/sirupsen/logrus" -) - -// LogrusHandler converts logrus hook to log handler. -func LogrusHandler(hook logrus.Hook) log.Handler { - return log.FuncHandler(func(r *log.Record) error { - data := &logrus.Entry{ - Message: r.Msg, - Data: fields(r.Ctx), - } - return hook.Fire(data) - }) -} - -func fields(ctx []interface{}) logrus.Fields { - ff := make(logrus.Fields, len(ctx)/2) - for i := 1; i < len(ctx); i += 2 { - k, ok := ctx[i-1].(string) - if !ok { - continue - } - ff[k] = ctx[i] - } - - return ff -} diff --git a/evm/go-x1/logger/periodic_log.go b/evm/go-x1/logger/periodic_log.go deleted file mode 100644 index ee7d5a3..0000000 --- a/evm/go-x1/logger/periodic_log.go +++ /dev/null @@ -1,51 +0,0 @@ -package logger - -import ( - "time" -) - -// Periodic is the same as logger.Instance, but writes only once in a period -type Periodic struct { - Instance - prevLogTime time.Time -} - -// Info is timed log.Info -func (l *Periodic) Info(period time.Duration, msg string, ctx ...interface{}) { - if time.Since(l.prevLogTime) > period { - l.Log.Info(msg, ctx...) - l.prevLogTime = time.Now() - } -} - -// Warn is timed log.Warn -func (l *Periodic) Warn(period time.Duration, msg string, ctx ...interface{}) { - if time.Since(l.prevLogTime) > period { - l.Log.Warn(msg, ctx...) - l.prevLogTime = time.Now() - } -} - -// Error is timed log.Error -func (l *Periodic) Error(period time.Duration, msg string, ctx ...interface{}) { - if time.Since(l.prevLogTime) > period { - l.Log.Error(msg, ctx...) - l.prevLogTime = time.Now() - } -} - -// Debug is timed log.Debug -func (l *Periodic) Debug(period time.Duration, msg string, ctx ...interface{}) { - if time.Since(l.prevLogTime) > period { - l.Log.Debug(msg, ctx...) - l.prevLogTime = time.Now() - } -} - -// Trace is timed log.Trace -func (l *Periodic) Trace(period time.Duration, msg string, ctx ...interface{}) { - if time.Since(l.prevLogTime) > period { - l.Log.Trace(msg, ctx...) - l.prevLogTime = time.Now() - } -} diff --git a/evm/go-x1/logger/test_output.go b/evm/go-x1/logger/test_output.go deleted file mode 100644 index 87d48f5..0000000 --- a/evm/go-x1/logger/test_output.go +++ /dev/null @@ -1,21 +0,0 @@ -package logger - -import ( - "testing" - - "github.com/ethereum/go-ethereum/log" -) - -// SetTestMode sets test mode. -func SetTestMode(t testing.TB) { - log.Root().SetHandler( - log.CallerStackHandler("%v", TestHandler(t, log.LogfmtFormat()))) -} - -// TestHandler writes into test log. -func TestHandler(t testing.TB, fmtr log.Format) log.Handler { - return log.FuncHandler(func(r *log.Record) error { - t.Log(string(fmtr.Format(r))) - return nil - }) -} diff --git a/evm/go-x1/opera/contracts/driver/driver_predeploy.go b/evm/go-x1/opera/contracts/driver/driver_predeploy.go deleted file mode 100644 index 82bdbfa..0000000 --- a/evm/go-x1/opera/contracts/driver/driver_predeploy.go +++ /dev/null @@ -1,17 +0,0 @@ -package driver - -import ( - "github.com/Fantom-foundation/go-opera/gossip/contract/driver100" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -// GetContractBin is NodeDriver contract genesis implementation bin code -// Has to be compiled with flag bin-runtime -// Built from opera-sfc be4e79d5a5a425f08efd6d65b588a72ae90f706f, solc 0.5.17+commit.d19bba13.Emscripten.clang, optimize-runs 10000 -func GetContractBin() []byte { - return hexutil.MustDecode(driver100.ContractBinRuntime) -} - -// ContractAddress is the NodeDriver contract address -var ContractAddress = common.HexToAddress("0xd100a01e00000000000000000000000000000000") diff --git a/evm/go-x1/opera/contracts/driver/drivercall/driver_calls.go b/evm/go-x1/opera/contracts/driver/drivercall/driver_calls.go deleted file mode 100644 index 6d1b6af..0000000 --- a/evm/go-x1/opera/contracts/driver/drivercall/driver_calls.go +++ /dev/null @@ -1,83 +0,0 @@ -package drivercall - -import ( - "math/big" - "strings" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera" - "github.com/Fantom-foundation/go-opera/opera/genesis/gpos" - "github.com/Fantom-foundation/go-opera/utils" -) - -const ContractABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"num\",\"type\":\"uint256\"}],\"name\":\"AdvanceEpochs\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"diff\",\"type\":\"bytes\"}],\"name\":\"UpdateNetworkRules\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"UpdateNetworkVersion\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"}],\"name\":\"UpdateValidatorPubkey\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"name\":\"UpdateValidatorWeight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"backend\",\"type\":\"address\"}],\"name\":\"UpdatedBackend\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_backend\",\"type\":\"address\"}],\"name\":\"setBackend\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_backend\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_evmWriterAddress\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"copyCode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"with\",\"type\":\"address\"}],\"name\":\"swapCode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"value\",\"type\":\"bytes32\"}],\"name\":\"setStorage\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"diff\",\"type\":\"uint256\"}],\"name\":\"incNonce\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"diff\",\"type\":\"bytes\"}],\"name\":\"updateNetworkRules\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateNetworkVersion\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"num\",\"type\":\"uint256\"}],\"name\":\"advanceEpochs\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"updateValidatorWeight\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"}],\"name\":\"updateValidatorPubkey\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_auth\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedTime\",\"type\":\"uint256\"}],\"name\":\"setGenesisValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockedStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupFromEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupEndTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyUnlockPenalty\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"}],\"name\":\"setGenesisDelegation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"}],\"name\":\"deactivateValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nextValidatorIDs\",\"type\":\"uint256[]\"}],\"name\":\"sealEpochValidators\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"offlineTimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"offlineBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"uptimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"originatedTxsFee\",\"type\":\"uint256[]\"}],\"name\":\"sealEpoch\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"offlineTimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"offlineBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"uptimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"originatedTxsFee\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"usedGas\",\"type\":\"uint256\"}],\"name\":\"sealEpochV1\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -var ( - sAbi, _ = abi.JSON(strings.NewReader(ContractABI)) -) - -type Delegation struct { - Address common.Address - ValidatorID idx.ValidatorID - Stake *big.Int - LockedStake *big.Int - LockupFromEpoch idx.Epoch - LockupEndTime idx.Epoch - LockupDuration uint64 - EarlyUnlockPenalty *big.Int - Rewards *big.Int -} - -// Methods - -func SealEpochValidators(_validators []idx.ValidatorID) []byte { - validators := make([]*big.Int, len(_validators)) - for i, v := range _validators { - validators[i] = utils.U64toBig(uint64(v)) - } - data, _ := sAbi.Pack("sealEpochValidators", validators) - return data -} - -type ValidatorEpochMetric struct { - Missed opera.BlocksMissed - Uptime inter.Timestamp - OriginatedTxFee *big.Int -} - -func SealEpoch(metrics []ValidatorEpochMetric) []byte { - offlineTimes := make([]*big.Int, len(metrics)) - offlineBlocks := make([]*big.Int, len(metrics)) - uptimes := make([]*big.Int, len(metrics)) - originatedTxFees := make([]*big.Int, len(metrics)) - for i, m := range metrics { - offlineTimes[i] = utils.U64toBig(uint64(m.Missed.Period.Unix())) - offlineBlocks[i] = utils.U64toBig(uint64(m.Missed.BlocksNum)) - uptimes[i] = utils.U64toBig(uint64(m.Uptime.Unix())) - originatedTxFees[i] = m.OriginatedTxFee - } - - data, _ := sAbi.Pack("sealEpoch", offlineTimes, offlineBlocks, uptimes, originatedTxFees) - return data -} - -func SetGenesisValidator(v gpos.Validator) []byte { - data, _ := sAbi.Pack("setGenesisValidator", v.Address, utils.U64toBig(uint64(v.ID)), v.PubKey.Bytes(), utils.U64toBig(v.Status), - utils.U64toBig(uint64(v.CreationEpoch)), utils.U64toBig(uint64(v.CreationTime.Unix())), utils.U64toBig(uint64(v.DeactivatedEpoch)), - utils.U64toBig(uint64(v.DeactivatedTime.Unix()))) - return data -} - -func SetGenesisDelegation(d Delegation) []byte { - data, _ := sAbi.Pack("setGenesisDelegation", d.Address, utils.U64toBig(uint64(d.ValidatorID)), d.Stake, d.LockedStake, utils.U64toBig(uint64(d.LockupFromEpoch)), utils.U64toBig(uint64(d.LockupEndTime)), utils.U64toBig(uint64(d.LockupDuration)), d.EarlyUnlockPenalty, d.Rewards) - return data -} - -func DeactivateValidator(validatorID idx.ValidatorID, status uint64) []byte { - data, _ := sAbi.Pack("deactivateValidator", utils.U64toBig(uint64(validatorID)), utils.U64toBig(status)) - return data -} diff --git a/evm/go-x1/opera/contracts/driver/driverpos/positions.go b/evm/go-x1/opera/contracts/driver/driverpos/positions.go deleted file mode 100644 index 49fc4c9..0000000 --- a/evm/go-x1/opera/contracts/driver/driverpos/positions.go +++ /dev/null @@ -1,24 +0,0 @@ -package driverpos - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -// Events -var ( - // Topics of Driver contract logs - Topics = struct { - UpdateValidatorWeight common.Hash - UpdateValidatorPubkey common.Hash - UpdateNetworkRules common.Hash - UpdateNetworkVersion common.Hash - AdvanceEpochs common.Hash - }{ - UpdateValidatorWeight: crypto.Keccak256Hash([]byte("UpdateValidatorWeight(uint256,uint256)")), - UpdateValidatorPubkey: crypto.Keccak256Hash([]byte("UpdateValidatorPubkey(uint256,bytes)")), - UpdateNetworkRules: crypto.Keccak256Hash([]byte("UpdateNetworkRules(bytes)")), - UpdateNetworkVersion: crypto.Keccak256Hash([]byte("UpdateNetworkVersion(uint256)")), - AdvanceEpochs: crypto.Keccak256Hash([]byte("AdvanceEpochs(uint256)")), - } -) diff --git a/evm/go-x1/opera/contracts/driverauth/driverauth.go b/evm/go-x1/opera/contracts/driverauth/driverauth.go deleted file mode 100644 index 64e92a8..0000000 --- a/evm/go-x1/opera/contracts/driverauth/driverauth.go +++ /dev/null @@ -1,17 +0,0 @@ -package driverauth - -import ( - "github.com/Fantom-foundation/go-opera/gossip/contract/driverauth100" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -// GetContractBin is NodeDriverAuth contract genesis implementation bin code -// Has to be compiled with flag bin-runtime -// Built from opera-sfc be4e79d5a5a425f08efd6d65b588a72ae90f706f, solc 0.5.17+commit.d19bba13.Emscripten.clang, optimize-runs 10000 -func GetContractBin() []byte { - return hexutil.MustDecode(driverauth100.ContractBinRuntime) -} - -// ContractAddress is the NodeDriverAuth contract address -var ContractAddress = common.HexToAddress("0xd100ae0000000000000000000000000000000000") diff --git a/evm/go-x1/opera/contracts/emitterdriver/emitterdriver.go b/evm/go-x1/opera/contracts/emitterdriver/emitterdriver.go deleted file mode 100644 index d4207ef..0000000 --- a/evm/go-x1/opera/contracts/emitterdriver/emitterdriver.go +++ /dev/null @@ -1,6 +0,0 @@ -package emitterdriver - -import "github.com/ethereum/go-ethereum/common" - -// ContractAddress is the EmitterDriver contract address -var ContractAddress = common.HexToAddress("0xee00d10000000000000000000000000000000000") diff --git a/evm/go-x1/opera/contracts/evmwriter/evm_writer.go b/evm/go-x1/opera/contracts/evmwriter/evm_writer.go deleted file mode 100644 index df602bb..0000000 --- a/evm/go-x1/opera/contracts/evmwriter/evm_writer.go +++ /dev/null @@ -1,202 +0,0 @@ -package evmwriter - -import ( - "bytes" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/opera/contracts/driver" -) - -var ( - // ContractAddress is the EvmWriter pre-compiled contract address - ContractAddress = common.HexToAddress("0xd100ec0000000000000000000000000000000000") - // ContractABI is the input ABI used to generate the binding from - ContractABI string = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"num\",\"type\":\"uint256\"}],\"name\":\"AdvanceEpochs\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"diff\",\"type\":\"bytes\"}],\"name\":\"UpdateNetworkRules\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"UpdateNetworkVersion\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"}],\"name\":\"UpdateValidatorPubkey\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"name\":\"UpdateValidatorWeight\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"backend\",\"type\":\"address\"}],\"name\":\"UpdatedBackend\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_backend\",\"type\":\"address\"}],\"name\":\"setBackend\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_backend\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_evmWriterAddress\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"copyCode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"with\",\"type\":\"address\"}],\"name\":\"swapCode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"value\",\"type\":\"bytes32\"}],\"name\":\"setStorage\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"acc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"diff\",\"type\":\"uint256\"}],\"name\":\"incNonce\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"diff\",\"type\":\"bytes\"}],\"name\":\"updateNetworkRules\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateNetworkVersion\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"num\",\"type\":\"uint256\"}],\"name\":\"advanceEpochs\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"updateValidatorWeight\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"}],\"name\":\"updateValidatorPubkey\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_auth\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pubkey\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"createdTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deactivatedTime\",\"type\":\"uint256\"}],\"name\":\"setGenesisValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"toValidatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockedStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupFromEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupEndTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockupDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyUnlockPenalty\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"}],\"name\":\"setGenesisDelegation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"validatorID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"status\",\"type\":\"uint256\"}],\"name\":\"deactivateValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nextValidatorIDs\",\"type\":\"uint256[]\"}],\"name\":\"sealEpochValidators\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"offlineTimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"offlineBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"uptimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"originatedTxsFee\",\"type\":\"uint256[]\"}],\"name\":\"sealEpoch\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"offlineTimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"offlineBlocks\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"uptimes\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"originatedTxsFee\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"usedGas\",\"type\":\"uint256\"}],\"name\":\"sealEpochV1\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" -) - -var ( - setBalanceMethodID []byte - copyCodeMethodID []byte - swapCodeMethodID []byte - setStorageMethodID []byte - incNonceMethodID []byte -) - -func init() { - abi, err := abi.JSON(strings.NewReader(ContractABI)) - if err != nil { - panic(err) - } - - for name, constID := range map[string]*[]byte{ - "setBalance": &setBalanceMethodID, - "copyCode": ©CodeMethodID, - "swapCode": &swapCodeMethodID, - "setStorage": &setStorageMethodID, - "incNonce": &incNonceMethodID, - } { - method, exist := abi.Methods[name] - if !exist { - panic("unknown EvmWriter method") - } - - *constID = make([]byte, len(method.ID)) - copy(*constID, method.ID) - } -} - -type PreCompiledContract struct{} - -func (_ PreCompiledContract) Run(stateDB vm.StateDB, _ vm.BlockContext, txCtx vm.TxContext, caller common.Address, input []byte, suppliedGas uint64) ([]byte, uint64, error) { - if caller != driver.ContractAddress { - return nil, 0, vm.ErrExecutionReverted - } - if len(input) < 4 { - return nil, 0, vm.ErrExecutionReverted - } - if bytes.Equal(input[:4], setBalanceMethodID) { - input = input[4:] - // setBalance - if suppliedGas < params.CallValueTransferGas { - return nil, 0, vm.ErrOutOfGas - } - suppliedGas -= params.CallValueTransferGas - if len(input) != 64 { - return nil, 0, vm.ErrExecutionReverted - } - - acc := common.BytesToAddress(input[12:32]) - input = input[32:] - value := new(big.Int).SetBytes(input[:32]) - - if acc == txCtx.Origin { - // Origin balance shouldn't decrease during his transaction - return nil, 0, vm.ErrExecutionReverted - } - - balance := stateDB.GetBalance(acc) - if balance.Cmp(value) >= 0 { - diff := new(big.Int).Sub(balance, value) - stateDB.SubBalance(acc, diff) - } else { - diff := new(big.Int).Sub(value, balance) - stateDB.AddBalance(acc, diff) - } - } else if bytes.Equal(input[:4], copyCodeMethodID) { - input = input[4:] - // copyCode - if suppliedGas < params.CreateGas { - return nil, 0, vm.ErrOutOfGas - } - suppliedGas -= params.CreateGas - if len(input) != 64 { - return nil, 0, vm.ErrExecutionReverted - } - - accTo := common.BytesToAddress(input[12:32]) - input = input[32:] - accFrom := common.BytesToAddress(input[12:32]) - - code := stateDB.GetCode(accFrom) - if code == nil { - code = []byte{} - } - cost := uint64(len(code)) * (params.CreateDataGas + params.MemoryGas) - if suppliedGas < cost { - return nil, 0, vm.ErrOutOfGas - } - suppliedGas -= cost - if accTo != accFrom { - stateDB.SetCode(accTo, code) - } - } else if bytes.Equal(input[:4], swapCodeMethodID) { - input = input[4:] - // swapCode - cost := 2 * params.CreateGas - if suppliedGas < cost { - return nil, 0, vm.ErrOutOfGas - } - suppliedGas -= cost - if len(input) != 64 { - return nil, 0, vm.ErrExecutionReverted - } - - acc0 := common.BytesToAddress(input[12:32]) - input = input[32:] - acc1 := common.BytesToAddress(input[12:32]) - code0 := stateDB.GetCode(acc0) - if code0 == nil { - code0 = []byte{} - } - code1 := stateDB.GetCode(acc1) - if code1 == nil { - code1 = []byte{} - } - cost0 := uint64(len(code0)) * (params.CreateDataGas + params.MemoryGas) - cost1 := uint64(len(code1)) * (params.CreateDataGas + params.MemoryGas) - cost = (cost0 + cost1) / 2 // 50% discount because trie size won't increase after pruning - if suppliedGas < cost { - return nil, 0, vm.ErrOutOfGas - } - suppliedGas -= cost - if acc0 != acc1 { - stateDB.SetCode(acc0, code1) - stateDB.SetCode(acc1, code0) - } - } else if bytes.Equal(input[:4], setStorageMethodID) { - input = input[4:] - // setStorage - if suppliedGas < params.SstoreSetGasEIP2200 { - return nil, 0, vm.ErrOutOfGas - } - suppliedGas -= params.SstoreSetGasEIP2200 - if len(input) != 96 { - return nil, 0, vm.ErrExecutionReverted - } - acc := common.BytesToAddress(input[12:32]) - input = input[32:] - key := common.BytesToHash(input[:32]) - input = input[32:] - value := common.BytesToHash(input[:32]) - - stateDB.SetState(acc, key, value) - } else if bytes.Equal(input[:4], incNonceMethodID) { - input = input[4:] - // incNonce - if suppliedGas < params.CallValueTransferGas { - return nil, 0, vm.ErrOutOfGas - } - suppliedGas -= params.CallValueTransferGas - if len(input) != 64 { - return nil, 0, vm.ErrExecutionReverted - } - - acc := common.BytesToAddress(input[12:32]) - input = input[32:] - value := new(big.Int).SetBytes(input[:32]) - - if acc == txCtx.Origin { - // Origin nonce shouldn't change during his transaction - return nil, 0, vm.ErrExecutionReverted - } - - if value.Cmp(common.Big256) >= 0 { - // Don't allow large nonce increasing to prevent a nonce overflow - return nil, 0, vm.ErrExecutionReverted - } - if value.Sign() <= 0 { - return nil, 0, vm.ErrExecutionReverted - } - - stateDB.SetNonce(acc, stateDB.GetNonce(acc)+value.Uint64()) - } else { - return nil, 0, vm.ErrExecutionReverted - } - return nil, suppliedGas, nil -} diff --git a/evm/go-x1/opera/contracts/evmwriter/evm_writer_test.go b/evm/go-x1/opera/contracts/evmwriter/evm_writer_test.go deleted file mode 100644 index 6f38abf..0000000 --- a/evm/go-x1/opera/contracts/evmwriter/evm_writer_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package evmwriter - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestSign(t *testing.T) { - require := require.New(t) - - require.Equal([]byte{0xe3, 0x04, 0x43, 0xbc}, setBalanceMethodID) - require.Equal([]byte{0xd6, 0xa0, 0xc7, 0xaf}, copyCodeMethodID) - require.Equal([]byte{0x07, 0x69, 0x0b, 0x2a}, swapCodeMethodID) - require.Equal([]byte{0x39, 0xe5, 0x03, 0xab}, setStorageMethodID) - require.Equal([]byte{0x79, 0xbe, 0xad, 0x38}, incNonceMethodID) - -} diff --git a/evm/go-x1/opera/contracts/netinit/netinitcalls/network_initializer_calls.go b/evm/go-x1/opera/contracts/netinit/netinitcalls/network_initializer_calls.go deleted file mode 100644 index 7b5f721..0000000 --- a/evm/go-x1/opera/contracts/netinit/netinitcalls/network_initializer_calls.go +++ /dev/null @@ -1,25 +0,0 @@ -package netinitcall - -import ( - "math/big" - "strings" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - - "github.com/Fantom-foundation/go-opera/utils" -) - -const ContractABI = "[{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"sealedEpoch\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"},{\"internalType\":\"addresspayable\",\"name\":\"_sfc\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_lib\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_auth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_driver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_evmWriter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"initializeAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -var ( - sAbi, _ = abi.JSON(strings.NewReader(ContractABI)) -) - -// Methods - -func InitializeAll(sealedEpoch idx.Epoch, totalSupply *big.Int, sfcAddr common.Address, libAddr common.Address, driverAuthAddr common.Address, driverAddr common.Address, evmWriterAddr common.Address, owner common.Address) []byte { - data, _ := sAbi.Pack("initializeAll", utils.U64toBig(uint64(sealedEpoch)), totalSupply, sfcAddr, libAddr, driverAuthAddr, driverAddr, evmWriterAddr, owner) - return data -} diff --git a/evm/go-x1/opera/contracts/netinit/network_initializer.go b/evm/go-x1/opera/contracts/netinit/network_initializer.go deleted file mode 100644 index 8339aed..0000000 --- a/evm/go-x1/opera/contracts/netinit/network_initializer.go +++ /dev/null @@ -1,17 +0,0 @@ -package netinit - -import ( - "github.com/Fantom-foundation/go-opera/gossip/contract/netinit100" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -// GetContractBin is NetworkInitializer contract genesis implementation bin code -// Has to be compiled with flag bin-runtime -// Built from opera-sfc be4e79d5a5a425f08efd6d65b588a72ae90f706f, solc 0.5.17+commit.d19bba13.Emscripten.clang, optimize-runs 10000 -func GetContractBin() []byte { - return hexutil.MustDecode(netinit100.ContractBinRuntime) -} - -// ContractAddress is the NetworkInitializer contract address -var ContractAddress = common.HexToAddress("0xd1005eed00000000000000000000000000000000") diff --git a/evm/go-x1/opera/contracts/sfc/sfc_predeploy.go b/evm/go-x1/opera/contracts/sfc/sfc_predeploy.go deleted file mode 100644 index 0e1c6c4..0000000 --- a/evm/go-x1/opera/contracts/sfc/sfc_predeploy.go +++ /dev/null @@ -1,17 +0,0 @@ -package sfc - -import ( - "github.com/Fantom-foundation/go-opera/gossip/contract/sfc100" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -// GetContractBin is SFC contract genesis implementation bin code -// Has to be compiled with flag bin-runtime -// Built from opera-sfc be4e79d5a5a425f08efd6d65b588a72ae90f706f, solc 0.5.17+commit.d19bba13.Emscripten.clang, optimize-runs 200 -func GetContractBin() []byte { - return hexutil.MustDecode(sfc100.ContractBinRuntime) -} - -// ContractAddress is the SFC contract address -var ContractAddress = common.HexToAddress("0xfc00face00000000000000000000000000000000") diff --git a/evm/go-x1/opera/contracts/sfclib/sfclib_predeploy.go b/evm/go-x1/opera/contracts/sfclib/sfclib_predeploy.go deleted file mode 100644 index af33d84..0000000 --- a/evm/go-x1/opera/contracts/sfclib/sfclib_predeploy.go +++ /dev/null @@ -1,17 +0,0 @@ -package sfclib - -import ( - "github.com/Fantom-foundation/go-opera/gossip/contract/sfclib100" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -// GetContractBin is SFCLib contract genesis implementation bin code -// Has to be compiled with flag bin-runtime -// Built from opera-sfc be4e79d5a5a425f08efd6d65b588a72ae90f706f, solc 0.5.17+commit.d19bba13.Emscripten.clang, optimize-runs 200 -func GetContractBin() []byte { - return hexutil.MustDecode(sfclib100.ContractBinRuntime) -} - -// ContractAddress is the SFCLib contract address -var ContractAddress = common.HexToAddress("0xfc01face00000000000000000000000000000000") diff --git a/evm/go-x1/opera/genesis/gpos/validators.go b/evm/go-x1/opera/genesis/gpos/validators.go deleted file mode 100644 index 86d21b9..0000000 --- a/evm/go-x1/opera/genesis/gpos/validators.go +++ /dev/null @@ -1,52 +0,0 @@ -package gpos - -import ( - "github.com/Fantom-foundation/go-opera/inter" - "github.com/ethereum/go-ethereum/common" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -type ( - // Validator is a helper structure to define genesis validators - Validator struct { - ID idx.ValidatorID - Address common.Address - PubKey validatorpk.PubKey - CreationTime inter.Timestamp - CreationEpoch idx.Epoch - DeactivatedTime inter.Timestamp - DeactivatedEpoch idx.Epoch - Status uint64 - } - - Validators []Validator -) - -// Map converts Validators to map -func (gv Validators) Map() map[idx.ValidatorID]Validator { - validators := map[idx.ValidatorID]Validator{} - for _, val := range gv { - validators[val.ID] = val - } - return validators -} - -// PubKeys returns not sorted genesis pub keys -func (gv Validators) PubKeys() []validatorpk.PubKey { - res := make([]validatorpk.PubKey, 0, len(gv)) - for _, v := range gv { - res = append(res, v.PubKey) - } - return res -} - -// Addresses returns not sorted genesis addresses -func (gv Validators) Addresses() []common.Address { - res := make([]common.Address, 0, len(gv)) - for _, v := range gv { - res = append(res, v.Address) - } - return res -} diff --git a/evm/go-x1/opera/genesis/types.go b/evm/go-x1/opera/genesis/types.go deleted file mode 100644 index c3637d9..0000000 --- a/evm/go-x1/opera/genesis/types.go +++ /dev/null @@ -1,67 +0,0 @@ -package genesis - -import ( - "fmt" - "sort" - "strings" - - "github.com/Fantom-foundation/lachesis-base/hash" - - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" -) - -type ( - Hashes map[string]hash.Hash - Header struct { - GenesisID hash.Hash - NetworkID uint64 - NetworkName string - } - Blocks interface { - ForEach(fn func(ibr.LlrIdxFullBlockRecord) bool) - } - Epochs interface { - ForEach(fn func(ier.LlrIdxFullEpochRecord) bool) - } - EvmItems interface { - ForEach(fn func(key, value []byte) bool) - } - Genesis struct { - Header - - Blocks Blocks - Epochs Epochs - RawEvmItems EvmItems - } -) - -func (hh Hashes) Includes(hh2 Hashes) bool { - for n, h := range hh { - if hh2[n] != h { - return false - } - } - return true -} - -func (hh Hashes) Equal(hh2 Hashes) bool { - return hh.Includes(hh2) && hh2.Includes(hh) -} - -func (hh Hashes) String() string { - bb := make([]string, 0, len(hh)) - for n, h := range hh { - bb = append(bb, fmt.Sprintf("%s: %s", n, h.String())) - } - sort.Strings(bb) - return "{" + strings.Join(bb, ", ") + "}" -} - -func (h Header) Equal(h2 Header) bool { - return h == h2 -} - -func (h Header) String() string { - return fmt.Sprintf("{%d, net:%s, id:%s}", h.NetworkID, h.NetworkName, h.GenesisID.String()) -} diff --git a/evm/go-x1/opera/genesisstore/disk.go b/evm/go-x1/opera/genesisstore/disk.go deleted file mode 100644 index 4919eb1..0000000 --- a/evm/go-x1/opera/genesisstore/disk.go +++ /dev/null @@ -1,167 +0,0 @@ -package genesisstore - -import ( - "bytes" - "compress/gzip" - "errors" - "fmt" - "io" - "strings" - "time" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/ethereum/go-ethereum/rlp" - "github.com/status-im/keycard-go/hexutils" - "github.com/syndtr/goleveldb/leveldb/opt" - - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/opera/genesisstore/filelog" - "github.com/Fantom-foundation/go-opera/opera/genesisstore/fileshash" - "github.com/Fantom-foundation/go-opera/opera/genesisstore/readersmap" - "github.com/Fantom-foundation/go-opera/utils/ioread" -) - -var ( - FileHeader = hexutils.HexToBytes("641b00ac") - FileVersion = hexutils.HexToBytes("00020001") -) - -const ( - FilesHashMaxMemUsage = 256 * opt.MiB - FilesHashPieceSize = 64 * opt.MiB -) - -type dummyByteReader struct { - io.Reader -} - -func (r dummyByteReader) ReadByte() (byte, error) { - b := make([]byte, 1) - err := ioread.ReadAll(r.Reader, b) - return b[0], err -} - -func checkFileHeader(reader io.Reader) error { - headerAndVersion := make([]byte, len(FileHeader)+len(FileVersion)) - err := ioread.ReadAll(reader, headerAndVersion) - if err != nil { - return err - } - if bytes.Compare(headerAndVersion[:len(FileHeader)], FileHeader) != 0 { - return errors.New("expected a genesis file, mismatched file header") - } - if bytes.Compare(headerAndVersion[len(FileHeader):], FileVersion) != 0 { - got := hexutils.BytesToHex(headerAndVersion[len(FileHeader):]) - expected := hexutils.BytesToHex(FileVersion) - return errors.New(fmt.Sprintf("wrong version of genesis file, got=%s, expected=%s", got, expected)) - } - return nil -} - -type ReadAtSeekerCloser interface { - io.ReaderAt - io.Seeker - io.Closer -} - -type Unit struct { - UnitName string - Header genesis.Header -} - -func OpenGenesisStore(rawReader ReadAtSeekerCloser) (*Store, genesis.Hashes, error) { - header := genesis.Header{} - hashes := genesis.Hashes{} - units := make([]readersmap.Unit, 0, 3) - offset := int64(0) - for i := 0; ; i++ { - // header cannot be long, cap it with 100000 bytes - headerReader := io.NewSectionReader(rawReader, offset, offset+100000) - err := checkFileHeader(headerReader) - if err == io.EOF { - break - } - if err != nil { - return nil, hashes, err - } - unit := Unit{} - err = rlp.Decode(dummyByteReader{headerReader}, &unit) - if err != nil { - return nil, hashes, err - } - if i == 0 { - header = unit.Header - } else { - if !header.Equal(unit.Header) { - return nil, hashes, errors.New("subsequent genesis header doesn't match the first header") - } - } - - var h hash.Hash - err = ioread.ReadAll(headerReader, h[:]) - if err != nil { - return nil, hashes, err - } - hashes[unit.UnitName] = h - - var numB [8]byte - err = ioread.ReadAll(headerReader, numB[:]) - if err != nil { - return nil, hashes, err - } - dataCompressedSize := bigendian.BytesToUint64(numB[:]) - - err = ioread.ReadAll(headerReader, numB[:]) - if err != nil { - return nil, hashes, err - } - uncompressedSize := bigendian.BytesToUint64(numB[:]) - - headerSize, err := headerReader.Seek(0, io.SeekCurrent) - if err != nil { - return nil, hashes, err - } - - unitReader := io.NewSectionReader(rawReader, offset+headerSize, offset+headerSize+int64(dataCompressedSize)) - offset += headerSize + int64(dataCompressedSize) - - gzipReader, err := gzip.NewReader(unitReader) - if err != nil { - return nil, hashes, err - } - - // wrap with a logger - // human-readable name - name := unit.UnitName - scanfName := strings.ReplaceAll(name, "-", "") - if scanfName[len(scanfName)-1] < '0' || scanfName[len(scanfName)-1] > '9' { - scanfName += "0" - } - var part int - if _, err := fmt.Sscanf(scanfName, "brs%d", &part); err == nil { - name = fmt.Sprintf("blocks unit %d", part) - } - if _, err := fmt.Sscanf(scanfName, "ers%d", &part); err == nil { - name = fmt.Sprintf("epochs unit %d", part) - } - if _, err := fmt.Sscanf(scanfName, "evm%d", &part); err == nil { - name = fmt.Sprintf("EVM unit %d", part) - } - loggedReader := filelog.Wrap(gzipReader, name, uncompressedSize, time.Minute) - - units = append(units, readersmap.Unit{ - Name: unit.UnitName, - Reader: loggedReader, - }) - } - - unitsMap, err := readersmap.Wrap(units) - if err != nil { - return nil, hashes, err - } - - hashedMap := fileshash.Wrap(unitsMap.Open, FilesHashMaxMemUsage, hashes) - - return NewStore(hashedMap, header, rawReader.Close), hashes, nil -} diff --git a/evm/go-x1/opera/genesisstore/filelog/filelog.go b/evm/go-x1/opera/genesisstore/filelog/filelog.go deleted file mode 100644 index b6c71b8..0000000 --- a/evm/go-x1/opera/genesisstore/filelog/filelog.go +++ /dev/null @@ -1,49 +0,0 @@ -package filelog - -import ( - "fmt" - "io" - "time" - - "github.com/ethereum/go-ethereum/log" - - "github.com/Fantom-foundation/go-opera/utils" -) - -type Filelog struct { - io.Reader - name string - size uint64 - period time.Duration - consumed uint64 - prevLog time.Time - start time.Time -} - -func (f *Filelog) Read(p []byte) (n int, err error) { - n, err = f.Reader.Read(p) - f.consumed += uint64(n) - if f.prevLog.IsZero() { - log.Info(fmt.Sprintf("- Reading %s", f.name)) - f.prevLog = time.Now() - f.start = time.Now() - } else if f.consumed > 0 && f.consumed < f.size && time.Since(f.prevLog) >= f.period { - elapsed := time.Since(f.start) - eta := float64(f.size-f.consumed) / float64(f.consumed) * float64(elapsed) - progress := float64(f.consumed) / float64(f.size) - eta *= 1.0 + (1.0-progress)/2.0 // show slightly higher ETA as performance degrades over larger volumes of data - progressStr := fmt.Sprintf("%.2f%%", 100*progress) - log.Info(fmt.Sprintf("- Reading %s", f.name), "progress", progressStr, "elapsed", utils.PrettyDuration(elapsed), "eta", utils.PrettyDuration(eta)) - f.prevLog = time.Now() - } - return -} - -func Wrap(r io.Reader, name string, size uint64, period time.Duration) *Filelog { - return &Filelog{ - Reader: r, - name: name, - size: size, - period: period, - } -} diff --git a/evm/go-x1/opera/genesisstore/fileshash/filehash_test.go b/evm/go-x1/opera/genesisstore/fileshash/filehash_test.go deleted file mode 100644 index e5073c4..0000000 --- a/evm/go-x1/opera/genesisstore/fileshash/filehash_test.go +++ /dev/null @@ -1,220 +0,0 @@ -package fileshash - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "math/rand" - "os" - "path" - "testing" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/utils/ioread" -) - -type dropableFile struct { - io.ReadWriteSeeker - io.Closer - path string -} - -func (f dropableFile) Drop() error { - return os.Remove(f.path) -} - -func TestFileHash_ReadWrite(t *testing.T) { - - const ( - FILE_CONTENT = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Nunc finibus ultricies interdum. Nulla porttitor arcu a tincidunt mollis. Aliquam erat volutpat. - Maecenas eget ligula mi. Maecenas in ligula non elit fringilla consequat. - Morbi non imperdiet odio. Integer viverra ligula a varius tempor. - Duis ac velit vel augue faucibus tincidunt ut ac nisl. Nulla sed magna est. - Etiam quis nunc in elit ultricies pulvinar sed at felis. - Suspendisse fringilla lectus vel est hendrerit pulvinar. - Vivamus nec lorem pharetra ligula pulvinar blandit in quis nunc. - Cras id eros fermentum mauris tristique faucibus. - Praesent vehicula lectus nec ipsum sollicitudin tempus. Nullam et massa velit.` - ) - t.Run("Large file, pieceSize=10000", func(t *testing.T) { - testFileHash_ReadWrite(t, bytes.Repeat([]byte(FILE_CONTENT), 20), hash.HexToHash("0xe3c3075749531525b472f4d6d70578e6d497d3e75b0727fea1ee10bdd1fcd490"), 10000) - }) - t.Run("Large file, pieceSize=100", func(t *testing.T) { - testFileHash_ReadWrite(t, bytes.Repeat([]byte(FILE_CONTENT), 20), hash.HexToHash("0xdc6d882fde82b2dd44884a97884d79be40e1d0f780a493dee0f7256d8261f7a5"), 100) - }) - t.Run("Medium file, pieceSize=1", func(t *testing.T) { - testFileHash_ReadWrite(t, bytes.Repeat([]byte(FILE_CONTENT), 1), hash.HexToHash("0x63a76929ee27decd5100d07a3cb626c05df1f1e927c5f27fa17c62459685ca6f"), 1) - }) - t.Run("Medium file, pieceSize=2", func(t *testing.T) { - testFileHash_ReadWrite(t, bytes.Repeat([]byte(FILE_CONTENT), 1), hash.HexToHash("0x2babd1049c449a60da62a1a0a3dc836e6a222dece07dcba1890a041d60ff29c7"), 2) - }) - t.Run("Medium file, pieceSize=100", func(t *testing.T) { - testFileHash_ReadWrite(t, bytes.Repeat([]byte(FILE_CONTENT), 1), hash.HexToHash("0x15c45aba675b7c49f5def32b4f24e827d478e5dfd712613fd6a5df69a2793b60"), 100) - }) - t.Run("Tiny file, pieceSize=1", func(t *testing.T) { - testFileHash_ReadWrite(t, []byte{0}, hash.HexToHash("0xbdda25ac486f2b8c0330a6fcace8f3d05d3e713b7920a39a1f60c0d8df024c0e"), 1) - }) - t.Run("Tiny file, pieceSize=2", func(t *testing.T) { - testFileHash_ReadWrite(t, []byte{0}, hash.HexToHash("0xf2b22424f7d1d01467d650f18ad49df8929fbefdeefe95e868d52eec6ea399e1"), 2) - }) - t.Run("Empty file, pieceSize=1", func(t *testing.T) { - testFileHash_ReadWrite(t, []byte{}, hash.HexToHash("0x9cbc73d18d70c94fe366e696035c4f2cffdbab7ea6d6c2c039ca185f9c9f2746"), 1) - }) - t.Run("Empty file, pieceSize=2", func(t *testing.T) { - testFileHash_ReadWrite(t, []byte{}, hash.HexToHash("0x163e7f66d58036ccb1d0b0058d8f46e7cd639816f570e5eb32853ea73634e4cd"), 2) - }) -} - -func testFileHash_ReadWrite(t *testing.T, content []byte, expRoot hash.Hash, pieceSize uint64) { - require := require.New(t) - tmpDirPath, err := ioutil.TempDir("", "filehash*") - defer os.RemoveAll(tmpDirPath) - require.NoError(err) - f, err := ioutil.TempFile(tmpDirPath, "testnet.g") - filePath := f.Name() - require.NoError(err) - writer := WrapWriter(f, pieceSize, func(i int) TmpWriter { - tmpFh, err := os.OpenFile(path.Join(tmpDirPath, fmt.Sprintf("genesis%d.dat", i)), os.O_CREATE|os.O_RDWR, os.ModePerm) - require.NoError(err) - return dropableFile{ - ReadWriteSeeker: tmpFh, - Closer: tmpFh, - path: tmpFh.Name(), - } - }) - - // write out the (secure) self-hashed file properly - _, err = writer.Write(content) - require.NoError(err) - root, err := writer.Flush() - require.NoError(err) - require.Equal(expRoot.Hex(), root.Hex()) - f.Close() - - maxMemUsage := memUsageOf(pieceSize, getPiecesNum(uint64(len(content)), pieceSize)) - - // normal case: correct root hash and content after reading file partially - if len(content) > 0 { - f, err = os.OpenFile(filePath, os.O_RDONLY, 0600) - require.NoError(err) - reader := WrapReader(f, maxMemUsage, root) - readB := make([]byte, rand.Int63n(int64(len(content)))) - err = ioread.ReadAll(reader, readB) - require.NoError(err) - require.Equal(content[:len(readB)], readB) - reader.Close() - } - - // normal case: correct root hash and content after reading the whole file - { - f, err = os.OpenFile(filePath, os.O_RDONLY, 0600) - require.NoError(err) - reader := WrapReader(f, maxMemUsage, root) - readB := make([]byte, len(content)) - err = ioread.ReadAll(reader, readB) - require.NoError(err) - require.Equal(content, readB) - // try to read one more byte - require.Error(ioread.ReadAll(reader, make([]byte, 1)), io.EOF) - reader.Close() - } - - // correct root hash and reading too much content - { - f, err = os.OpenFile(filePath, os.O_RDONLY, 0600) - require.NoError(err) - reader := WrapReader(f, maxMemUsage, root) - readB := make([]byte, len(content)+1) - require.Error(ioread.ReadAll(reader, readB), io.EOF) - reader.Close() - } - - // passing the wrong root hash to reader - { - f, err = os.OpenFile(filePath, os.O_RDONLY, 0600) - require.NoError(err) - maliciousReader := WrapReader(f, maxMemUsage, hash.HexToHash("0x00")) - data := make([]byte, 1) - err = ioread.ReadAll(maliciousReader, data) - require.Contains(err.Error(), ErrInit.Error()) - maliciousReader.Close() - } - - // modify piece data to make the mismatch piece hash - headerOffset := 4 + 8 + getPiecesNum(uint64(len(content)), pieceSize)*32 - if len(content) > 0 { - // mutate content byte - f, err = os.OpenFile(filePath, os.O_RDWR, 0600) - require.NoError(err) - s := []byte{0} - contentPos := rand.Int63n(int64(len(content))) - pos := int64(headerOffset) + contentPos - _, err = f.ReadAt(s, pos) - require.NoError(err) - s[0]++ - _, err = f.WriteAt(s, pos) - require.NoError(err) - require.NoError(f.Close()) - - // try to read - f, err = os.OpenFile(filePath, os.O_RDONLY, 0600) - maliciousReader := WrapReader(f, maxMemUsage, root) - data := make([]byte, contentPos+1) - err = ioread.ReadAll(maliciousReader, data) - require.Contains(err.Error(), ErrHashMismatch.Error()) - require.NoError(maliciousReader.Close()) - - // restore - s[0]-- - f, err = os.OpenFile(filePath, os.O_RDWR, 0600) - require.NoError(err) - _, err = f.WriteAt(s, pos) - require.NoError(err) - require.NoError(f.Close()) - } - - // modify a piece hash in file to make the wrong one - { - // mutate content byte - f, err = os.OpenFile(filePath, os.O_RDWR, 0600) - require.NoError(err) - pos := rand.Int63n(int64(headerOffset)) - s := []byte{0} - _, err = f.ReadAt(s, pos) - require.NoError(err) - s[0]++ - _, err = f.WriteAt(s, pos) - require.NoError(err) - require.NoError(f.Close()) - - // try to read - f, err = os.OpenFile(filePath, os.O_RDONLY, 0600) - maliciousReader := WrapReader(f, maxMemUsage*2, root) - data := make([]byte, 1) - err = ioread.ReadAll(maliciousReader, data) - require.Contains(err.Error(), ErrInit.Error()) - require.NoError(maliciousReader.Close()) - - // restore - s[0]-- - f, err = os.OpenFile(filePath, os.O_RDWR, 0600) - require.NoError(err) - _, err = f.WriteAt(s, pos) - require.NoError(err) - require.NoError(f.Close()) - } - - // hashed file requires too much memory - { - f, err = os.OpenFile(filePath, os.O_WRONLY, 0600) - require.NoError(err) - oomReader := WrapReader(f, maxMemUsage-1, root) - data := make([]byte, 1) - err = ioread.ReadAll(oomReader, data) - require.Errorf(err, "hashed file requires too much memory") - } -} diff --git a/evm/go-x1/opera/genesisstore/fileshash/reader_file.go b/evm/go-x1/opera/genesisstore/fileshash/reader_file.go deleted file mode 100644 index bdc5af3..0000000 --- a/evm/go-x1/opera/genesisstore/fileshash/reader_file.go +++ /dev/null @@ -1,210 +0,0 @@ -package fileshash - -import ( - "crypto/sha256" - "errors" - "fmt" - "io" - "math" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - - "github.com/Fantom-foundation/go-opera/utils/ioread" -) - -var ( - ErrRootNotFound = errors.New("hashes root not found") - ErrRootMismatch = errors.New("hashes root mismatch") - ErrHashMismatch = errors.New("hash mismatch") - ErrTooMuchMem = errors.New("hashed file requires too much memory") - ErrInit = errors.New("failed to init hashfile") - ErrPieceRead = errors.New("failed to read piece") - ErrClosed = errors.New("closed") -) - -type Reader struct { - backend io.Reader - - size uint64 - pos uint64 - - pieceSize uint64 - currentPiecePos uint64 - currentPiece []byte - - root hash.Hash - hashes hash.Hashes - - maxMemUsage uint64 - - err error -} - -func WrapReader(backend io.Reader, maxMemUsage uint64, root hash.Hash) *Reader { - return &Reader{ - backend: backend, - pos: 0, - maxMemUsage: maxMemUsage, - currentPiecePos: math.MaxUint64, - root: root, - } -} - -func (r *Reader) readHashes(n uint64) (hash.Hashes, error) { - hashes := make(hash.Hashes, n) - for i := uint64(0); i < n; i++ { - err := ioread.ReadAll(r.backend, hashes[i][:]) - if err != nil { - return nil, err - } - } - return hashes, nil -} - -func calcHash(piece []byte) hash.Hash { - hasher := sha256.New() - hasher.Write(piece) - return hash.BytesToHash(hasher.Sum(nil)) -} - -func calcHashesRoot(hashes hash.Hashes, pieceSize, size uint64) hash.Hash { - hasher := sha256.New() - hasher.Write(bigendian.Uint32ToBytes(uint32(pieceSize))) - hasher.Write(bigendian.Uint64ToBytes(size)) - for _, h := range hashes { - hasher.Write(h.Bytes()) - } - return hash.BytesToHash(hasher.Sum(nil)) -} - -func getPiecesNum(size, pieceSize uint64) uint64 { - if size%pieceSize != 0 { - return size/pieceSize + 1 - } - return size / pieceSize -} - -func (r *Reader) getPiecesNum(size uint64) uint64 { - return getPiecesNum(size, r.pieceSize) -} - -func (r *Reader) getPiecePos(pos uint64) uint64 { - return pos / r.pieceSize -} - -func (r *Reader) readNewPiece() error { - // previous piece must be fully read at this point - // ensure currentPiece has correct size - maxToRead := r.size - r.pos - if maxToRead > r.pieceSize { - maxToRead = r.pieceSize - } - if uint64(len(r.currentPiece)) > maxToRead { - r.currentPiece = r.currentPiece[:maxToRead] - } - if uint64(len(r.currentPiece)) < maxToRead { - r.currentPiece = make([]byte, maxToRead) - } - // read currentPiece - err := ioread.ReadAll(r.backend, r.currentPiece) - if err != nil { - return err - } - // verify piece hash and advance currentPiecePos - currentPiecePos := r.getPiecePos(r.pos) - if calcHash(r.currentPiece) != r.hashes[currentPiecePos] { - return ErrHashMismatch - } - r.currentPiecePos = currentPiecePos - return nil -} - -func (r *Reader) readFromPiece(p []byte) (n int, err error) { - if r.currentPiecePos != r.getPiecePos(r.pos) { - // switch to new piece - err := r.readNewPiece() - if err != nil { - return 0, fmt.Errorf("%v: %v", ErrPieceRead, err) - } - } - maxToRead := uint64(len(r.currentPiece)) - if maxToRead > uint64(len(p)) { - maxToRead = uint64(len(p)) - } - posInPiece := r.pos % r.pieceSize - consumed := copy(p[:maxToRead], r.currentPiece[posInPiece:]) - r.pos += uint64(consumed) - return consumed, nil -} - -func memUsageOf(pieceSize, hashesNum uint64) uint64 { - if hashesNum > math.MaxUint32 { - return math.MaxUint64 - } - return pieceSize + hashesNum*128 -} - -func (r *Reader) init() error { - buf := make([]byte, 8) - // read piece size - err := ioread.ReadAll(r.backend, buf[:4]) - if err != nil { - return err - } - r.pieceSize = uint64(bigendian.BytesToUint32(buf[:4])) - // read content size - err = ioread.ReadAll(r.backend, buf) - if err != nil { - return err - } - r.size = bigendian.BytesToUint64(buf) - - hashesNum := r.getPiecesNum(r.size) - if memUsageOf(r.pieceSize, hashesNum) > uint64(r.maxMemUsage) { - return ErrTooMuchMem - } - // read piece hashes - hashes, err := r.readHashes(hashesNum) - if err != nil { - return err - } - if calcHashesRoot(hashes, r.pieceSize, r.size) != r.root { - return ErrRootMismatch - } - r.hashes = hashes - return nil -} - -func (r *Reader) read(p []byte) (n int, err error) { - if len(p) == 0 { - return 0, nil - } - if r.hashes == nil { - err := r.init() - if err != nil { - return 0, fmt.Errorf("%v: %v", ErrInit, err) - } - } - if r.pos >= r.size { - return 0, io.EOF - } - return r.readFromPiece(p) -} - -func (r *Reader) Read(p []byte) (n int, err error) { - if r.err != nil { - return 0, r.err - } - n, err = r.read(p) - if err != nil { - r.err = err - } - return n, err -} - -func (r *Reader) Close() error { - r.hashes = nil - r.err = ErrClosed - return r.backend.(io.Closer).Close() -} diff --git a/evm/go-x1/opera/genesisstore/fileshash/reader_map.go b/evm/go-x1/opera/genesisstore/fileshash/reader_map.go deleted file mode 100644 index c3c80ae..0000000 --- a/evm/go-x1/opera/genesisstore/fileshash/reader_map.go +++ /dev/null @@ -1,25 +0,0 @@ -package fileshash - -import ( - "io" - - "github.com/Fantom-foundation/lachesis-base/hash" -) - -type Map struct { - backend func(string) (io.Reader, error) -} - -func Wrap(backend func(string) (io.Reader, error), maxMemoryUsage uint64, roots map[string]hash.Hash) func(string) (io.Reader, error) { - return func(name string) (io.Reader, error) { - root, ok := roots[name] - if !ok { - return nil, ErrRootNotFound - } - f, err := backend(name) - if err != nil { - return nil, err - } - return WrapReader(f, maxMemoryUsage, root), nil - } -} diff --git a/evm/go-x1/opera/genesisstore/fileshash/write_file.go b/evm/go-x1/opera/genesisstore/fileshash/write_file.go deleted file mode 100644 index aa430a7..0000000 --- a/evm/go-x1/opera/genesisstore/fileshash/write_file.go +++ /dev/null @@ -1,189 +0,0 @@ -package fileshash - -import ( - "crypto/sha256" - "errors" - hasher "hash" - "io" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/hash" - - "github.com/Fantom-foundation/go-opera/utils/ioread" -) - -type TmpWriter interface { - io.ReadWriteSeeker - io.Closer - Drop() error -} - -type tmpWriter struct { - TmpWriter - h hasher.Hash -} - -type Writer struct { - backend io.Writer - - openTmp func(int) TmpWriter - tmps []tmpWriter - tmpReadPos uint64 - - size uint64 - - pieceSize uint64 -} - -func WrapWriter(backend io.Writer, pieceSize uint64, openTmp func(int) TmpWriter) *Writer { - return &Writer{ - backend: backend, - openTmp: openTmp, - pieceSize: pieceSize, - } -} - -func (w *Writer) writeIntoTmp(p []byte) error { - if len(p) == 0 { - return nil - } - if w.size/w.pieceSize >= uint64(len(w.tmps)) { - tmpI := len(w.tmps) - f := w.openTmp(len(w.tmps)) - if tmpI > 0 { - err := w.tmps[tmpI-1].Close() - if err != nil { - return err - } - w.tmps[tmpI-1].TmpWriter = nil - } - w.tmps = append(w.tmps, tmpWriter{ - TmpWriter: f, - h: sha256.New(), - }) - } - currentPosInTmp := w.size % w.pieceSize - maxToWrite := w.pieceSize - currentPosInTmp - if maxToWrite > uint64(len(p)) { - maxToWrite = uint64(len(p)) - } - n, err := w.tmps[len(w.tmps)-1].Write(p[:maxToWrite]) - w.tmps[len(w.tmps)-1].h.Write(p[:maxToWrite]) - w.size += uint64(n) - if err != nil { - return err - } - return w.writeIntoTmp(p[maxToWrite:]) -} - -func (w *Writer) resetTmpReads() error { - for _, tmp := range w.tmps { - if tmp.TmpWriter != nil { - _, err := tmp.Seek(0, io.SeekStart) - if err != nil { - return err - } - } - } - w.tmpReadPos = 0 - return nil -} - -func (w *Writer) readFromTmp(p []byte, destructive bool) error { - if len(p) == 0 { - return nil - } - tmpI := w.tmpReadPos / w.pieceSize - if tmpI > uint64(len(w.tmps)) { - return errors.New("all tmp files are consumed") - } - if w.tmps[tmpI].TmpWriter == nil { - w.tmps[tmpI].TmpWriter = w.openTmp(int(tmpI)) - } - currentPosInTmp := w.tmpReadPos % w.pieceSize - maxToRead := w.pieceSize - currentPosInTmp - if maxToRead > uint64(len(p)) { - maxToRead = uint64(len(p)) - } - err := ioread.ReadAll(w.tmps[tmpI], p[:maxToRead]) - if err != nil { - return err - } - w.tmpReadPos += maxToRead - if w.tmpReadPos%w.pieceSize == 0 { - _ = w.tmps[tmpI].Close() - if destructive { - _ = w.tmps[tmpI].Drop() - } - w.tmps[tmpI].TmpWriter = nil - } - return w.readFromTmp(p[maxToRead:], destructive) -} - -func (w *Writer) Write(p []byte) (n int, err error) { - oldSize := w.size - err = w.writeIntoTmp(p) - n = int(w.size - oldSize) - return -} - -func (w *Writer) readFromTmpPieceByPiece(destructive bool, fn func([]byte) error) error { - err := w.resetTmpReads() - if err != nil { - return err - } - piece := make([]byte, w.pieceSize) - for pos := uint64(0); pos < w.size; pos += w.pieceSize { - end := pos + w.pieceSize - if end > w.size { - end = w.size - } - err := w.readFromTmp(piece[:end-pos], destructive) - if err != nil { - return err - } - err = fn(piece[:end-pos]) - if err != nil { - return err - } - } - return nil -} - -func (w *Writer) Root() hash.Hash { - hashes := hash.Hashes{} - for _, tmp := range w.tmps { - h := hash.BytesToHash(tmp.h.Sum(nil)) - hashes = append(hashes, h) - } - return calcHashesRoot(hashes, w.pieceSize, w.size) -} - -func (w *Writer) Flush() (hash.Hash, error) { - // write piece - _, err := w.backend.Write(bigendian.Uint32ToBytes(uint32(w.pieceSize))) - if err != nil { - return hash.Hash{}, err - } - // write size - _, err = w.backend.Write(bigendian.Uint64ToBytes(w.size)) - if err != nil { - return hash.Hash{}, err - } - // write piece hashes - hashes := hash.Hashes{} - for _, tmp := range w.tmps { - h := hash.BytesToHash(tmp.h.Sum(nil)) - hashes = append(hashes, h) - _, err = w.backend.Write(h[:]) - if err != nil { - return hash.Hash{}, err - } - } - root := calcHashesRoot(hashes, w.pieceSize, w.size) - // write data and drop tmp files - return root, w.readFromTmpPieceByPiece(true, func(piece []byte) error { - _, err := w.backend.Write(piece) - return err - }) -} diff --git a/evm/go-x1/opera/genesisstore/readersmap/reader_map.go b/evm/go-x1/opera/genesisstore/readersmap/reader_map.go deleted file mode 100644 index 62145b7..0000000 --- a/evm/go-x1/opera/genesisstore/readersmap/reader_map.go +++ /dev/null @@ -1,37 +0,0 @@ -package readersmap - -import ( - "errors" - "io" -) - -type Map map[string]io.Reader - -type Unit struct { - Name string - io.Reader -} - -var ( - ErrNotFound = errors.New("not found") - ErrDupFile = errors.New("unit name is duplicated") -) - -func Wrap(rr []Unit) (Map, error) { - units := make(Map) - for _, r := range rr { - if units[r.Name] != nil { - return nil, ErrDupFile - } - units[r.Name] = r.Reader - } - return units, nil -} - -func (mm Map) Open(name string) (io.Reader, error) { - f := mm[name] - if f == nil { - return nil, ErrNotFound - } - return f, nil -} diff --git a/evm/go-x1/opera/genesisstore/store.go b/evm/go-x1/opera/genesisstore/store.go deleted file mode 100644 index 2d41c7d..0000000 --- a/evm/go-x1/opera/genesisstore/store.go +++ /dev/null @@ -1,47 +0,0 @@ -package genesisstore - -import ( - "io" - - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/opera/genesis" -) - -func BlocksSection(i int) string { - return getSectionName("brs", i) -} - -func EpochsSection(i int) string { - return getSectionName("ers", i) -} - -func EvmSection(i int) string { - return getSectionName("evm", i) -} - -type FilesMap func(string) (io.Reader, error) - -// Store is a node persistent storage working over a physical zip archive. -type Store struct { - fMap FilesMap - head genesis.Header - close func() error - - logger.Instance -} - -// NewStore creates store over key-value db. -func NewStore(fMap FilesMap, head genesis.Header, close func() error) *Store { - return &Store{ - fMap: fMap, - head: head, - close: close, - Instance: logger.New("genesis-store"), - } -} - -// Close leaves underlying database. -func (s *Store) Close() error { - s.fMap = nil - return s.close() -} diff --git a/evm/go-x1/opera/genesisstore/store_genesis.go b/evm/go-x1/opera/genesisstore/store_genesis.go deleted file mode 100644 index a779f02..0000000 --- a/evm/go-x1/opera/genesisstore/store_genesis.go +++ /dev/null @@ -1,123 +0,0 @@ -package genesisstore - -import ( - "fmt" - "io" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/Fantom-foundation/go-opera/inter/ibr" - "github.com/Fantom-foundation/go-opera/inter/ier" - "github.com/Fantom-foundation/go-opera/opera/genesis" - "github.com/Fantom-foundation/go-opera/utils/iodb" -) - -type ( - Blocks struct { - fMap FilesMap - } - Epochs struct { - fMap FilesMap - } - RawEvmItems struct { - fMap FilesMap - } -) - -func (s *Store) Genesis() genesis.Genesis { - return genesis.Genesis{ - Header: s.head, - Blocks: s.Blocks(), - Epochs: s.Epochs(), - RawEvmItems: s.RawEvmItems(), - } -} - -func getSectionName(base string, i int) string { - if i == 0 { - return base - } - return fmt.Sprintf("%s-%d", base, i) -} - -func (s Store) Header() genesis.Header { - return s.head -} - -func (s *Store) Blocks() genesis.Blocks { - return Blocks{s.fMap} -} - -func (s Blocks) ForEach(fn func(ibr.LlrIdxFullBlockRecord) bool) { - for i := 1000; i >= 0; i-- { - f, err := s.fMap(BlocksSection(i)) - if err != nil { - continue - } - stream := rlp.NewStream(f, 0) - for { - br := ibr.LlrIdxFullBlockRecord{} - err = stream.Decode(&br) - if err == io.EOF { - break - } - if err != nil { - log.Crit("Failed to decode Blocks genesis section", "err", err) - } - if !fn(br) { - break - } - } - } -} - -func (s *Store) Epochs() genesis.Epochs { - return Epochs{s.fMap} -} - -func (s Epochs) ForEach(fn func(ier.LlrIdxFullEpochRecord) bool) { - for i := 1000; i >= 0; i-- { - f, err := s.fMap(EpochsSection(i)) - if err != nil { - continue - } - stream := rlp.NewStream(f, 0) - for { - er := ier.LlrIdxFullEpochRecord{} - err = stream.Decode(&er) - if err == io.EOF { - break - } - if err != nil { - log.Crit("Failed to decode Epochs genesis section", "err", err) - } - if !fn(er) { - break - } - } - } -} - -func (s *Store) RawEvmItems() genesis.EvmItems { - return RawEvmItems{s.fMap} -} - -func (s RawEvmItems) ForEach(fn func(key, value []byte) bool) { - for i := 1000; i >= 0; i-- { - f, err := s.fMap(EvmSection(i)) - if err != nil { - continue - } - it := iodb.NewIterator(f) - for it.Next() { - if !fn(it.Key(), it.Value()) { - break - } - } - if it.Error() != nil { - log.Crit("Failed to decode RawEvmItems genesis section", "err", it.Error()) - } - it.Release() - } -} diff --git a/evm/go-x1/opera/legacy_serialization.go b/evm/go-x1/opera/legacy_serialization.go deleted file mode 100644 index ce0abb7..0000000 --- a/evm/go-x1/opera/legacy_serialization.go +++ /dev/null @@ -1,175 +0,0 @@ -package opera - -import ( - "errors" - "io" - - "github.com/ethereum/go-ethereum/rlp" -) - -type GasRulesRLPV0 struct { - MaxEventGas uint64 - EventGas uint64 - ParentGas uint64 - ExtraDataGas uint64 -} - -// EncodeRLP is for RLP serialization. -func (r Rules) EncodeRLP(w io.Writer) error { - // write the type - rType := uint8(0) - if r.Upgrades != (Upgrades{}) { - rType = 1 - _, err := w.Write([]byte{rType}) - if err != nil { - return err - } - } - // write the main body - rlpR := RulesRLP(r) - err := rlp.Encode(w, &rlpR) - if err != nil { - return err - } - // write additional fields, depending on the type - if rType > 0 { - err := rlp.Encode(w, &r.Upgrades) - if err != nil { - return err - } - } - return nil -} - -// DecodeRLP is for RLP serialization. -func (r *Rules) DecodeRLP(s *rlp.Stream) error { - kind, _, err := s.Kind() - if err != nil { - return err - } - // read rType - rType := uint8(0) - if kind == rlp.Byte { - var b []byte - if b, err = s.Bytes(); err != nil { - return err - } - if len(b) == 0 { - return errors.New("empty typed") - } - rType = b[0] - if rType == 0 || rType > 1 { - return errors.New("unknown type") - } - } - // decode the main body - rlpR := RulesRLP{} - err = s.Decode(&rlpR) - if err != nil { - return err - } - *r = Rules(rlpR) - // decode additional fields, depending on the type - if rType >= 1 { - err = s.Decode(&r.Upgrades) - if err != nil { - return err - } - } - return nil -} - -// EncodeRLP is for RLP serialization. -func (u Upgrades) EncodeRLP(w io.Writer) error { - bitmap := struct { - V uint64 - }{} - if u.Berlin { - bitmap.V |= berlinBit - } - if u.London { - bitmap.V |= londonBit - } - if u.Llr { - bitmap.V |= llrBit - } - return rlp.Encode(w, &bitmap) -} - -// DecodeRLP is for RLP serialization. -func (u *Upgrades) DecodeRLP(s *rlp.Stream) error { - bitmap := struct { - V uint64 - }{} - err := s.Decode(&bitmap) - if err != nil { - return err - } - u.Berlin = (bitmap.V & berlinBit) != 0 - u.London = (bitmap.V & londonBit) != 0 - u.Llr = (bitmap.V & llrBit) != 0 - return nil -} - -// EncodeRLP is for RLP serialization. -func (r GasRules) EncodeRLP(w io.Writer) error { - // write the type - rType := uint8(0) - if r.EpochVoteGas != 0 || r.MisbehaviourProofGas != 0 || r.BlockVotesBaseGas != 0 || r.BlockVoteGas != 0 { - rType = 1 - _, err := w.Write([]byte{rType}) - if err != nil { - return err - } - } - if rType == 0 { - return rlp.Encode(w, &GasRulesRLPV0{ - MaxEventGas: r.MaxEventGas, - EventGas: r.EventGas, - ParentGas: r.ParentGas, - ExtraDataGas: r.ExtraDataGas, - }) - } else { - return rlp.Encode(w, (*GasRulesRLPV1)(&r)) - } -} - -// DecodeRLP is for RLP serialization. -func (r *GasRules) DecodeRLP(s *rlp.Stream) error { - kind, _, err := s.Kind() - if err != nil { - return err - } - // read rType - rType := uint8(0) - if kind == rlp.Byte { - var b []byte - if b, err = s.Bytes(); err != nil { - return err - } - if len(b) == 0 { - return errors.New("empty typed") - } - rType = b[0] - if rType == 0 || rType > 1 { - return errors.New("unknown type") - } - } - // decode the main body - if rType == 0 { - rlpR := GasRulesRLPV0{} - err = s.Decode(&rlpR) - if err != nil { - return err - } - *r = GasRules{ - MaxEventGas: rlpR.MaxEventGas, - EventGas: rlpR.EventGas, - ParentGas: rlpR.ParentGas, - ExtraDataGas: rlpR.ExtraDataGas, - } - return nil - } else { - return s.Decode((*GasRulesRLPV1)(r)) - } -} diff --git a/evm/go-x1/opera/marshal.go b/evm/go-x1/opera/marshal.go deleted file mode 100644 index 7dc6b4b..0000000 --- a/evm/go-x1/opera/marshal.go +++ /dev/null @@ -1,16 +0,0 @@ -package opera - -import "encoding/json" - -func UpdateRules(src Rules, diff []byte) (res Rules, err error) { - changed := src.Copy() - err = json.Unmarshal(diff, &changed) - if err != nil { - return src, err - } - // protect readonly fields - res = changed - res.NetworkID = src.NetworkID - res.Name = src.Name - return -} diff --git a/evm/go-x1/opera/marshal_test.go b/evm/go-x1/opera/marshal_test.go deleted file mode 100644 index 5f7dcc6..0000000 --- a/evm/go-x1/opera/marshal_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package opera - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/rlp" - "github.com/stretchr/testify/require" -) - -func TestUpdateRules(t *testing.T) { - require := require.New(t) - - var exp Rules - exp.Epochs.MaxEpochGas = 99 - - exp.Dag.MaxParents = 5 - exp.Economy.MinGasPrice = big.NewInt(7) - exp.Blocks.MaxBlockGas = 1000 - got, err := UpdateRules(exp, []byte(`{"Dag":{"MaxParents":5},"Economy":{"MinGasPrice":7},"Blocks":{"MaxBlockGas":1000}}`)) - require.NoError(err) - require.Equal(exp.String(), got.String(), "mutate fields") - - exp.Dag.MaxParents = 0 - got, err = UpdateRules(exp, []byte(`{"Name":"xxx","NetworkID":1,"Dag":{"MaxParents":0}}`)) - require.NoError(err) - require.Equal(exp.String(), got.String(), "readonly fields") - - got, err = UpdateRules(exp, []byte(`{}`)) - require.NoError(err) - require.Equal(exp.String(), got.String(), "empty diff") - - _, err = UpdateRules(exp, []byte(`}{`)) - require.Error(err) -} - -func TestMainNetRulesRLP(t *testing.T) { - rules := MainNetRules() - require := require.New(t) - - b, err := rlp.EncodeToBytes(rules) - require.NoError(err) - - decodedRules := Rules{} - require.NoError(rlp.DecodeBytes(b, &decodedRules)) - - require.Equal(rules.String(), decodedRules.String()) -} - -func TestRulesBerlinRLP(t *testing.T) { - rules := MainNetRules() - rules.Upgrades.Berlin = true - require := require.New(t) - - b, err := rlp.EncodeToBytes(rules) - require.NoError(err) - - decodedRules := Rules{} - require.NoError(rlp.DecodeBytes(b, &decodedRules)) - - require.Equal(rules.String(), decodedRules.String()) - require.True(decodedRules.Upgrades.Berlin) -} - -func TestRulesLondonRLP(t *testing.T) { - rules := MainNetRules() - rules.Upgrades.London = true - rules.Upgrades.Berlin = true - require := require.New(t) - - b, err := rlp.EncodeToBytes(rules) - require.NoError(err) - - decodedRules := Rules{} - require.NoError(rlp.DecodeBytes(b, &decodedRules)) - - require.Equal(rules.String(), decodedRules.String()) - require.True(decodedRules.Upgrades.Berlin) - require.True(decodedRules.Upgrades.London) -} - -func TestRulesBerlinCompatibilityRLP(t *testing.T) { - require := require.New(t) - - b1, err := rlp.EncodeToBytes(Upgrades{ - Berlin: true, - }) - require.NoError(err) - - b2, err := rlp.EncodeToBytes(struct { - Berlin bool - }{true}) - require.NoError(err) - - require.Equal(b2, b1) -} - -func TestGasRulesLLRCompatibilityRLP(t *testing.T) { - require := require.New(t) - - b1, err := rlp.EncodeToBytes(GasRules{ - MaxEventGas: 1, - EventGas: 2, - ParentGas: 3, - ExtraDataGas: 4, - BlockVotesBaseGas: 0, - BlockVoteGas: 0, - EpochVoteGas: 0, - MisbehaviourProofGas: 0, - }) - require.NoError(err) - - b2, err := rlp.EncodeToBytes(struct { - MaxEventGas uint64 - EventGas uint64 - ParentGas uint64 - ExtraDataGas uint64 - }{1, 2, 3, 4}) - require.NoError(err) - - require.Equal(b2, b1) -} diff --git a/evm/go-x1/opera/rules.go b/evm/go-x1/opera/rules.go deleted file mode 100644 index e6e4acb..0000000 --- a/evm/go-x1/opera/rules.go +++ /dev/null @@ -1,335 +0,0 @@ -package opera - -import ( - "encoding/json" - "math/big" - "time" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - ethparams "github.com/ethereum/go-ethereum/params" - - "github.com/Fantom-foundation/go-opera/inter" - "github.com/Fantom-foundation/go-opera/opera/contracts/evmwriter" -) - -const ( - MainNetworkID uint64 = 0x31CE0 - TestNetworkID uint64 = 0x31CE5 - FakeNetworkID uint64 = 0xfa3 - DefaultEventGas uint64 = 28000 - berlinBit = 1 << 0 - londonBit = 1 << 1 - llrBit = 1 << 2 - TestnetStartBalance = 328333333 - TestnetStartStake = 5000000 - TestnetGenesisTime = inter.Timestamp(1700783108 * time.Second) -) - -var DefaultVMConfig = vm.Config{ - StatePrecompiles: map[common.Address]vm.PrecompiledStateContract{ - evmwriter.ContractAddress: &evmwriter.PreCompiledContract{}, - }, -} - -var GenesisValidators = []GenesisValidator{ - { - "0x1149aD69030084b780C5c375b252E73235AAe0d0", - "046e4a62824c79b42995e1144d6650dfc673029d4670dcbbdadce57f630a87e613b10cacb66f0f65995dfeedb7339af34c7d5e2031adc621c6bc0df78549726060", - }, - { - "0x9c11DafF4913c68838ce7ce6969b12BaBff4318b", - "04dfc5e6a7594905af4ea831847367e22e9a02c2669d5b00407800e616e1504ab8c847d1e42c118230e593c010e0466b33410450d01811700d562e14a98c521b8f", - }, - { - "0xa12f1025aF20f6C13385CdCFE5fc897496F87d98", - "04b2366cb5269d81cd00e0db9f808c43f614b44dc3abd25f54b025af498a579e7dd13de4f7573360690b23b22b2527a518ecf37119b8a03c8afc9fdbdbac98667e", - }, -} - -type GenesisValidator struct { - AccountAddress string - ValidatorPubKey string -} - -type RulesRLP struct { - Name string - NetworkID uint64 - - // Graph options - Dag DagRules - - // Epochs options - Epochs EpochsRules - - // Blockchain options - Blocks BlocksRules - - // Economy options - Economy EconomyRules - - Upgrades Upgrades `rlp:"-"` -} - -// Rules describes opera net. -// Note keep track of all the non-copiable variables in Copy() -type Rules RulesRLP - -// GasPowerRules defines gas power rules in the consensus. -type GasPowerRules struct { - AllocPerSec uint64 - MaxAllocPeriod inter.Timestamp - StartupAllocPeriod inter.Timestamp - MinStartupGas uint64 -} - -type GasRulesRLPV1 struct { - MaxEventGas uint64 - EventGas uint64 - ParentGas uint64 - ExtraDataGas uint64 - // Post-LLR fields - BlockVotesBaseGas uint64 - BlockVoteGas uint64 - EpochVoteGas uint64 - MisbehaviourProofGas uint64 -} - -type GasRules GasRulesRLPV1 - -type EpochsRules struct { - MaxEpochGas uint64 - MaxEpochDuration inter.Timestamp -} - -// DagRules of Lachesis DAG (directed acyclic graph). -type DagRules struct { - MaxParents idx.Event - MaxFreeParents idx.Event // maximum number of parents with no gas cost - MaxExtraData uint32 -} - -// BlocksMissed is information about missed blocks from a staker -type BlocksMissed struct { - BlocksNum idx.Block - Period inter.Timestamp -} - -// EconomyRules contains economy constants -type EconomyRules struct { - BlockMissedSlack idx.Block - - Gas GasRules - - MinGasPrice *big.Int - - ShortGasPower GasPowerRules - LongGasPower GasPowerRules -} - -// BlocksRules contains blocks constants -type BlocksRules struct { - MaxBlockGas uint64 // technical hard limit, gas is mostly governed by gas power allocation - MaxEmptyBlockSkipPeriod inter.Timestamp -} - -type Upgrades struct { - Berlin bool - London bool - Llr bool -} - -type UpgradeHeight struct { - Upgrades Upgrades - Height idx.Block -} - -// EvmChainConfig returns ChainConfig for transactions signing and execution -func (r Rules) EvmChainConfig(hh []UpgradeHeight) *ethparams.ChainConfig { - cfg := *ethparams.AllEthashProtocolChanges - cfg.ChainID = new(big.Int).SetUint64(r.NetworkID) - cfg.BerlinBlock = nil - cfg.LondonBlock = nil - for i, h := range hh { - height := new(big.Int) - if i > 0 { - height.SetUint64(uint64(h.Height)) - } - if cfg.BerlinBlock == nil && h.Upgrades.Berlin { - cfg.BerlinBlock = height - } - if !h.Upgrades.Berlin { - cfg.BerlinBlock = nil - } - - if cfg.LondonBlock == nil && h.Upgrades.London { - cfg.LondonBlock = height - } - if !h.Upgrades.London { - cfg.LondonBlock = nil - } - } - return &cfg -} - -func MainNetRules() Rules { - return Rules{ - Name: "main", - NetworkID: MainNetworkID, - Dag: DefaultDagRules(), - Epochs: DefaultEpochsRules(), - Economy: DefaultEconomyRules(), - Blocks: BlocksRules{ - MaxBlockGas: 20500000, - MaxEmptyBlockSkipPeriod: inter.Timestamp(1 * time.Minute), - }, - } -} - -func TestNetRules() Rules { - return Rules{ - Name: "x1-testnet", - NetworkID: TestNetworkID, - Dag: DefaultDagRules(), - Epochs: DefaultEpochsRules(), - Economy: TestnetEconomyRules(), - Blocks: BlocksRules{ - MaxBlockGas: 20500000, - MaxEmptyBlockSkipPeriod: inter.Timestamp(1 * time.Minute), - }, - Upgrades: Upgrades{ - Berlin: true, - London: true, - Llr: true, - }, - } -} - -func FakeNetRules() Rules { - return Rules{ - Name: "fake", - NetworkID: FakeNetworkID, - Dag: DefaultDagRules(), - Epochs: FakeNetEpochsRules(), - Economy: FakeEconomyRules(), - Blocks: BlocksRules{ - MaxBlockGas: 20500000, - MaxEmptyBlockSkipPeriod: inter.Timestamp(3 * time.Second), - }, - Upgrades: Upgrades{ - Berlin: true, - London: true, - Llr: true, - }, - } -} - -// DefaultEconomyRules returns mainnet economy -func DefaultEconomyRules() EconomyRules { - return EconomyRules{ - BlockMissedSlack: 50, - Gas: DefaultGasRules(), - MinGasPrice: big.NewInt(1e9), - ShortGasPower: DefaultShortGasPowerRules(), - LongGasPower: DefaulLongGasPowerRules(), - } -} - -func TestnetEconomyRules() EconomyRules { - return EconomyRules{ - BlockMissedSlack: 50, - Gas: DefaultGasRules(), - MinGasPrice: big.NewInt(5e11), - ShortGasPower: DefaultShortGasPowerRules(), - LongGasPower: DefaulLongGasPowerRules(), - } -} - -// FakeEconomyRules returns fakenet economy -func FakeEconomyRules() EconomyRules { - cfg := DefaultEconomyRules() - cfg.ShortGasPower = FakeShortGasPowerRules() - cfg.LongGasPower = FakeLongGasPowerRules() - return cfg -} - -func DefaultDagRules() DagRules { - return DagRules{ - MaxParents: 10, - MaxFreeParents: 3, - MaxExtraData: 128, - } -} - -func DefaultEpochsRules() EpochsRules { - return EpochsRules{ - MaxEpochGas: 1500000000, - MaxEpochDuration: inter.Timestamp(4 * time.Hour), - } -} - -func DefaultGasRules() GasRules { - return GasRules{ - MaxEventGas: 10000000 + DefaultEventGas, - EventGas: DefaultEventGas, - ParentGas: 2400, - ExtraDataGas: 25, - BlockVotesBaseGas: 1024, - BlockVoteGas: 512, - EpochVoteGas: 1536, - MisbehaviourProofGas: 71536, - } -} - -func FakeNetEpochsRules() EpochsRules { - cfg := DefaultEpochsRules() - cfg.MaxEpochGas /= 5 - cfg.MaxEpochDuration = inter.Timestamp(10 * time.Minute) - return cfg -} - -// DefaulLongGasPowerRules is long-window config -func DefaulLongGasPowerRules() GasPowerRules { - return GasPowerRules{ - AllocPerSec: 100 * DefaultEventGas, - MaxAllocPeriod: inter.Timestamp(60 * time.Minute), - StartupAllocPeriod: inter.Timestamp(5 * time.Second), - MinStartupGas: DefaultEventGas * 20, - } -} - -// DefaultShortGasPowerRules is short-window config -func DefaultShortGasPowerRules() GasPowerRules { - // 2x faster allocation rate, 6x lower max accumulated gas power - cfg := DefaulLongGasPowerRules() - cfg.AllocPerSec *= 2 - cfg.StartupAllocPeriod /= 2 - cfg.MaxAllocPeriod /= 2 * 6 - return cfg -} - -// FakeLongGasPowerRules is fake long-window config -func FakeLongGasPowerRules() GasPowerRules { - config := DefaulLongGasPowerRules() - config.AllocPerSec *= 1000 - return config -} - -// FakeShortGasPowerRules is fake short-window config -func FakeShortGasPowerRules() GasPowerRules { - config := DefaultShortGasPowerRules() - config.AllocPerSec *= 1000 - return config -} - -func (r Rules) Copy() Rules { - cp := r - cp.Economy.MinGasPrice = new(big.Int).Set(r.Economy.MinGasPrice) - return cp -} - -func (r Rules) String() string { - b, _ := json.Marshal(&r) - return string(b) -} diff --git a/evm/go-x1/sonar-project.properties b/evm/go-x1/sonar-project.properties deleted file mode 100644 index a80b2b7..0000000 --- a/evm/go-x1/sonar-project.properties +++ /dev/null @@ -1,9 +0,0 @@ -sonar.projectKey=Fantom-foundation_go-opera -sonar.projectName=go-opera - -sonar.sources=. -sonar.exclusions=**/*_test.go,**/vendor/** - -sonar.tests=. -sonar.test.inclusions=**/*_test.go -sonar.test.exclusions=**/vendor/** diff --git a/evm/go-x1/topicsdb/index.go b/evm/go-x1/topicsdb/index.go deleted file mode 100644 index 5b47951..0000000 --- a/evm/go-x1/topicsdb/index.go +++ /dev/null @@ -1,141 +0,0 @@ -package topicsdb - -import ( - "context" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/batched" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -// index is a specialized indexes for log records storing and fetching. -type index struct { - table struct { - // topic+topicN+(blockN+TxHash+logIndex) -> topic_count (where topicN=0 is for address) - Topic kvdb.Store `table:"t"` - // (blockN+TxHash+logIndex) -> ordered topic_count topics, blockHash, address, data - Logrec kvdb.Store `table:"r"` - } -} - -func newIndex(dbs kvdb.DBProducer) *index { - tt := &index{} - - err := table.OpenTables(&tt.table, dbs, "evm-logs") - if err != nil { - panic(err) - } - - return tt -} - -func (tt *index) WrapTablesAsBatched() (unwrap func()) { - origTables := tt.table - batchedTopic := batched.Wrap(tt.table.Topic) - tt.table.Topic = batchedTopic - batchedLogrec := batched.Wrap(tt.table.Logrec) - tt.table.Logrec = batchedLogrec - return func() { - _ = batchedTopic.Flush() - _ = batchedLogrec.Flush() - tt.table = origTables - } -} - -// FindInBlocks returns all log records of block range by pattern. 1st pattern element is an address. -func (tt *index) FindInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash) (logs []*types.Log, err error) { - err = tt.ForEachInBlocks( - ctx, - from, to, - pattern, - func(l *types.Log) bool { - logs = append(logs, l) - return true - }) - - return -} - -// ForEachInBlocks matches log records of block range by pattern. 1st pattern element is an address. -func (tt *index) ForEachInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash, onLog func(*types.Log) (gonext bool)) error { - if 0 < to && to < from { - return nil - } - - pattern, err := limitPattern(pattern) - if err != nil { - return err - } - - onMatched := func(rec *logrec) (gonext bool, err error) { - rec.fetch(tt.table.Logrec) - if rec.err != nil { - err = rec.err - return - } - gonext = onLog(rec.result) - return - } - - return tt.searchParallel(ctx, pattern, uint64(from), uint64(to), onMatched, doNothing) -} - -func doNothing() {} - -// Push log record to database batch -func (tt *index) Push(recs ...*types.Log) error { - for _, rec := range recs { - if len(rec.Topics) > maxTopicsCount { - return ErrTooBigTopics - } - - id := NewID(rec.BlockNumber, rec.TxHash, rec.Index) - - // write data - buf := make([]byte, 0, common.HashLength*len(rec.Topics)+common.HashLength+common.AddressLength+len(rec.Data)) - for _, topic := range rec.Topics { - buf = append(buf, topic.Bytes()...) - } - buf = append(buf, rec.BlockHash.Bytes()...) - buf = append(buf, rec.Address.Bytes()...) - buf = append(buf, rec.Data...) - if err := tt.table.Logrec.Put(id.Bytes(), buf); err != nil { - return err - } - - // write index - var ( - count = posToBytes(uint8(len(rec.Topics))) - pos uint8 - ) - pushIndex := func(topic common.Hash) error { - key := topicKey(topic, pos, id) - if err := tt.table.Topic.Put(key, count); err != nil { - return err - } - pos++ - return nil - } - - if err := pushIndex(rec.Address.Hash()); err != nil { - return err - } - - for _, topic := range rec.Topics { - if err := pushIndex(topic); err != nil { - return err - } - } - - } - - return nil -} - -func (tt *index) Close() { - _ = tt.table.Topic.Close() - _ = tt.table.Logrec.Close() -} diff --git a/evm/go-x1/topicsdb/key.go b/evm/go-x1/topicsdb/key.go deleted file mode 100644 index c399555..0000000 --- a/evm/go-x1/topicsdb/key.go +++ /dev/null @@ -1,82 +0,0 @@ -package topicsdb - -import ( - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/ethereum/go-ethereum/common" -) - -const ( - uint8Size = 1 - uint64Size = 8 - hashSize = common.HashLength - - logrecKeySize = uint64Size + hashSize + uint64Size - topicKeySize = hashSize + uint8Size + logrecKeySize - otherKeySize = logrecKeySize + uint8Size -) - -type ( - // ID of log record - ID [logrecKeySize]byte -) - -func NewID(block uint64, tx common.Hash, logIndex uint) (id ID) { - copy(id[:], uintToBytes(block)) - copy(id[uint64Size:], tx.Bytes()) - copy(id[uint64Size+hashSize:], uintToBytes(uint64(logIndex))) - return -} - -func (id *ID) Bytes() []byte { - return (*id)[:] -} - -func (id *ID) BlockNumber() uint64 { - return bytesToUint((*id)[:uint64Size]) -} - -func (id *ID) TxHash() (tx common.Hash) { - copy(tx[:], (*id)[uint64Size:uint64Size+hashSize]) - return -} - -func (id *ID) Index() uint { - return uint(bytesToUint( - (*id)[uint64Size+hashSize : uint64Size+hashSize+uint64Size])) -} - -func topicKey(topic common.Hash, pos uint8, logrec ID) []byte { - key := make([]byte, 0, topicKeySize) - - key = append(key, topic.Bytes()...) - key = append(key, posToBytes(pos)...) - key = append(key, logrec.Bytes()...) - - return key -} - -func posToBytes(pos uint8) []byte { - return []byte{pos} -} - -func bytesToPos(b []byte) uint8 { - return uint8(b[0]) -} - -func uintToBytes(n uint64) []byte { - return bigendian.Uint64ToBytes(n) -} - -func bytesToUint(b []byte) uint64 { - return bigendian.BytesToUint64(b) -} - -func extractLogrecID(key []byte) (id ID) { - switch len(key) { - case topicKeySize: - copy(id[:], key[hashSize+uint8Size:]) - return - default: - panic("wrong key type") - } -} diff --git a/evm/go-x1/topicsdb/key_test.go b/evm/go-x1/topicsdb/key_test.go deleted file mode 100644 index c8e7588..0000000 --- a/evm/go-x1/topicsdb/key_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package topicsdb - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestPosToBytes(t *testing.T) { - require := require.New(t) - - for i := 0xff / 0x0f; i >= 0; i-- { - expect := uint8(0x0f * i) - bb := posToBytes(expect) - got := bytesToPos(bb) - - require.Equal(expect, got) - } -} diff --git a/evm/go-x1/topicsdb/record.go b/evm/go-x1/topicsdb/record.go deleted file mode 100644 index a807ecb..0000000 --- a/evm/go-x1/topicsdb/record.go +++ /dev/null @@ -1,62 +0,0 @@ -package topicsdb - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -type ( - logrec struct { - ID ID - topicsCount uint8 - result *types.Log - err error - - matched int - } -) - -func newLogrec(rec ID, topicCount uint8) *logrec { - return &logrec{ - ID: rec, - topicsCount: topicCount, - } -} - -// fetch record's data. -func (rec *logrec) fetch( - logrecTable kvdb.Reader, -) { - r := &types.Log{ - BlockNumber: rec.ID.BlockNumber(), - TxHash: rec.ID.TxHash(), - Index: rec.ID.Index(), - Topics: make([]common.Hash, rec.topicsCount), - } - - var ( - buf []byte - offset int - ) - buf, rec.err = logrecTable.Get(rec.ID.Bytes()) - if rec.err != nil { - return - } - - // topics - for i := 0; i < len(r.Topics); i++ { - r.Topics[i] = common.BytesToHash(buf[offset : offset+common.HashLength]) - offset += common.HashLength - } - - // fields - r.BlockHash = common.BytesToHash(buf[offset : offset+common.HashLength]) - offset += common.HashLength - r.Address = common.BytesToAddress(buf[offset : offset+common.AddressLength]) - offset += common.AddressLength - r.Data = buf[offset:] - - rec.result = r - return -} diff --git a/evm/go-x1/topicsdb/search_parallel.go b/evm/go-x1/topicsdb/search_parallel.go deleted file mode 100644 index c1449ce..0000000 --- a/evm/go-x1/topicsdb/search_parallel.go +++ /dev/null @@ -1,121 +0,0 @@ -package topicsdb - -import ( - "context" - "sync" - - "github.com/ethereum/go-ethereum/common" -) - -type logHandler func(rec *logrec) (gonext bool, err error) - -func (tt *index) searchParallel(ctx context.Context, pattern [][]common.Hash, blockStart, blockEnd uint64, onMatched logHandler, onDbIterator func()) error { - if ctx == nil { - ctx = context.Background() - } - - var ( - syncing = newSynchronizator() - mu sync.Mutex - foundByBlock = make(map[uint64]map[ID]*logrec) - ) - - aggregator := func(pos, num int) logHandler { - return func(rec *logrec) (gonext bool, err error) { - if rec == nil { - syncing.FinishThread(pos, num) - return - } - - err = ctx.Err() - if err != nil { - return - } - - block := rec.ID.BlockNumber() - if blockEnd > 0 && block > blockEnd { - return - } - if rec.topicsCount < uint8(len(pattern)-1) { - gonext = true - return - } - - var prevBlock uint64 - prevBlock, gonext = syncing.GoNext(block) - if !gonext { - return - } - - mu.Lock() - defer mu.Unlock() - - if prevBlock > 0 { - delete(foundByBlock, prevBlock) - } - - found, ok := foundByBlock[block] - if !ok { - found = make(map[ID]*logrec) - foundByBlock[block] = found - } - - if before, ok := found[rec.ID]; ok { - rec = before - } else { - found[rec.ID] = rec - } - rec.matched++ - if rec.matched == syncing.PositionsCount() { - gonext, err = onMatched(rec) - if !gonext { - syncing.Halt() - return - } - } - - return - } - } - - // start the threads - var preparing sync.WaitGroup - preparing.Add(1) - for pos := range pattern { - if len(pattern[pos]) == 0 { - continue - } - for i, variant := range pattern[pos] { - syncing.StartThread(pos, i) - go func(pos, i int, variant common.Hash) { - onMatched := aggregator(pos, i) - preparing.Wait() - tt.scanPatternVariant(uint8(pos), variant, blockStart, onMatched, onDbIterator) - }(pos, i, variant) - } - } - preparing.Done() - - syncing.WaitForThreads() - - return ctx.Err() -} - -func (tt *index) scanPatternVariant(pos uint8, variant common.Hash, start uint64, onMatched logHandler, onDbIterator func()) { - prefix := append(variant.Bytes(), posToBytes(pos)...) - - onDbIterator() - it := tt.table.Topic.NewIterator(prefix, uintToBytes(start)) - defer it.Release() - for it.Next() { - id := extractLogrecID(it.Key()) - topicCount := bytesToPos(it.Value()) - rec := newLogrec(id, topicCount) - - gonext, _ := onMatched(rec) - if !gonext { - break - } - } - onMatched(nil) -} diff --git a/evm/go-x1/topicsdb/search_test.go b/evm/go-x1/topicsdb/search_test.go deleted file mode 100644 index 96b3a8d..0000000 --- a/evm/go-x1/topicsdb/search_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package topicsdb - -import ( - "context" - "testing" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" -) - -func BenchmarkSearch(b *testing.B) { - topics, recs, topics4rec := genTestData(1000) - - index := newTestIndex() - - for _, rec := range recs { - err := index.Push(rec) - require.NoError(b, err) - } - - var query [][][]common.Hash - for i := 0; i < len(topics); i++ { - from, to := topics4rec(i) - tt := topics[from : to-1] - - qq := make([][]common.Hash, len(tt)) - for pos, t := range tt { - qq[pos] = []common.Hash{t} - } - - query = append(query, qq) - } - - pooled := withThreadPool{index} - - for dsc, method := range map[string]func(context.Context, idx.Block, idx.Block, [][]common.Hash) ([]*types.Log, error){ - "index": index.FindInBlocks, - "pooled": pooled.FindInBlocks, - } { - b.Run(dsc, func(b *testing.B) { - b.ResetTimer() - - for i := 0; i < b.N; i++ { - qq := query[i%len(query)] - _, err := method(nil, 0, 0xffffffff, qq) - require.NoError(b, err) - } - }) - } -} diff --git a/evm/go-x1/topicsdb/sync.go b/evm/go-x1/topicsdb/sync.go deleted file mode 100644 index 446d0be..0000000 --- a/evm/go-x1/topicsdb/sync.go +++ /dev/null @@ -1,141 +0,0 @@ -package topicsdb - -import ( - "math" - "sync" -) - -type ( - posCounter struct { - pos int - count int - } - - blockCounter struct { - wait chan struct{} - count int - } - - synchronizator struct { - mu sync.Mutex - threads sync.WaitGroup - positions map[int]*posCounter - goNext bool - minBlock uint64 - blocks map[uint64]*blockCounter - } -) - -func newSynchronizator() *synchronizator { - s := &synchronizator{ - positions: make(map[int]*posCounter), - goNext: true, - minBlock: 0, - blocks: make(map[uint64]*blockCounter), - } - - return s -} - -func (s *synchronizator) Halt() { - s.goNext = false - - s.mu.Lock() - defer s.mu.Unlock() - - for n := range s.blocks { - if n != s.minBlock { - close(s.blocks[n].wait) - } - } -} - -func (s *synchronizator) GoNext(n uint64) (prev uint64, gonext bool) { - if !s.goNext { - return - } - - if n > s.minBlock { - s.mu.Lock() - prev = s.minBlock - s.enqueueBlock(n) - s.dequeueBlock() - wait := s.blocks[n].wait - s.mu.Unlock() - // wait for other threads - <-wait - } - - gonext = s.goNext - return -} - -func (s *synchronizator) StartThread(pos int, num int) { - s.threads.Add(1) - - s.mu.Lock() - defer s.mu.Unlock() - - s.enqueueBlock(s.minBlock) - - if _, ok := s.positions[pos]; ok { - s.positions[pos].count++ - } else { - s.positions[pos] = &posCounter{pos, 1} - } -} - -func (s *synchronizator) FinishThread(pos int, num int) { - s.threads.Done() - - s.mu.Lock() - defer s.mu.Unlock() - - s.positions[pos].count-- - s.dequeueBlock() -} - -func (s *synchronizator) enqueueBlock(n uint64) { - if _, ok := s.blocks[n]; ok { - s.blocks[n].count++ - } else { - s.blocks[n] = &blockCounter{ - wait: make(chan struct{}), - count: 1, - } - } -} - -func (s *synchronizator) dequeueBlock() { - s.blocks[s.minBlock].count-- - if s.blocks[s.minBlock].count < 1 { - - for _, pos := range s.positions { - if pos.count < 1 { - s.goNext = false - break - } - } - - delete(s.blocks, s.minBlock) - if len(s.blocks) < 1 { - return - } - // find new minBlock - s.minBlock = math.MaxUint64 - for b := range s.blocks { - if s.minBlock > b { - s.minBlock = b - } - } - close(s.blocks[s.minBlock].wait) - } -} - -func (s *synchronizator) WaitForThreads() { - s.threads.Wait() -} - -func (s *synchronizator) PositionsCount() int { - return len(s.positions) -} diff --git a/evm/go-x1/topicsdb/thread_pool.go b/evm/go-x1/topicsdb/thread_pool.go deleted file mode 100644 index 9768da1..0000000 --- a/evm/go-x1/topicsdb/thread_pool.go +++ /dev/null @@ -1,105 +0,0 @@ -package topicsdb - -import ( - "context" - "time" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/Fantom-foundation/go-opera/utils/dbutil/threads" -) - -// withThreadPool wraps the index and limits its threads in use -type withThreadPool struct { - *index -} - -// FindInBlocks returns all log records of block range by pattern. 1st pattern element is an address. -func (tt *withThreadPool) FindInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash) (logs []*types.Log, err error) { - err = tt.ForEachInBlocks( - ctx, - from, to, - pattern, - func(l *types.Log) bool { - logs = append(logs, l) - return true - }) - - return -} - -// ForEachInBlocks matches log records of block range by pattern. 1st pattern element is an address. -func (tt *withThreadPool) ForEachInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash, onLog func(*types.Log) (gonext bool)) error { - if 0 < to && to < from { - return nil - } - - if ctx == nil { - ctx = context.Background() - } - - pattern, err := limitPattern(pattern) - if err != nil { - return err - } - - onMatched := func(rec *logrec) (gonext bool, err error) { - rec.fetch(tt.table.Logrec) - if rec.err != nil { - err = rec.err - return - } - gonext = onLog(rec.result) - return - } - - splitby := 0 - parallels := 0 - for i := range pattern { - parallels += len(pattern[i]) - if len(pattern[splitby]) < len(pattern[i]) { - splitby = i - } - } - rest := pattern[splitby] - parallels -= len(rest) - - if parallels >= threads.GlobalPool.Cap() { - return ErrTooBigTopics - } - - for len(rest) > 0 { - got, release := threads.GlobalPool.Lock(parallels + len(rest)) - if got <= parallels { - release(got) - select { - case <-time.After(time.Millisecond): - continue - case <-ctx.Done(): - return ctx.Err() - } - } - - onDbIterator := func() { - release(1) - } - - pattern[splitby] = rest[:got-parallels] - rest = rest[got-parallels:] - err = tt.searchParallel(ctx, pattern, uint64(from), uint64(to), onMatched, onDbIterator) - if err != nil { - return err - } - } - - return nil -} - -func min(a, b int) int { - if a < b { - return a - } - return b -} diff --git a/evm/go-x1/topicsdb/topicsdb.go b/evm/go-x1/topicsdb/topicsdb.go deleted file mode 100644 index 65f43c7..0000000 --- a/evm/go-x1/topicsdb/topicsdb.go +++ /dev/null @@ -1,76 +0,0 @@ -package topicsdb - -import ( - "context" - "fmt" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -const maxTopicsCount = 5 // count is limited hard to 5 by EVM (see LOG0...LOG4 ops) - -var ( - ErrEmptyTopics = fmt.Errorf("empty topics") - ErrTooBigTopics = fmt.Errorf("too many topics") -) - -type Index interface { - FindInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash) (logs []*types.Log, err error) - ForEachInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash, onLog func(*types.Log) (gonext bool)) error - Push(recs ...*types.Log) error - Close() - - WrapTablesAsBatched() (unwrap func()) -} - -// New Index instance. -func New(dbs kvdb.DBProducer) Index { - tt := newIndex(dbs) - - return tt -} - -// New Index instance consumes limited threads count. -func NewWithThreadPool(dbs kvdb.DBProducer) Index { - tt := newIndex(dbs) - return &withThreadPool{tt} -} - -func limitPattern(pattern [][]common.Hash) (limited [][]common.Hash, err error) { - if len(pattern) > (maxTopicsCount + 1) { - limited = make([][]common.Hash, (maxTopicsCount + 1)) - } else { - limited = make([][]common.Hash, len(pattern)) - } - copy(limited, pattern) - - ok := false - for i, variants := range limited { - ok = ok || len(variants) > 0 - if len(variants) > 1 { - limited[i] = uniqOnly(variants) - } - } - if !ok { - err = ErrEmptyTopics - return - } - - return -} - -func uniqOnly(hh []common.Hash) []common.Hash { - index := make(map[common.Hash]struct{}, len(hh)) - for _, h := range hh { - index[h] = struct{}{} - } - - uniq := make([]common.Hash, 0, len(index)) - for h := range index { - uniq = append(uniq, h) - } - return uniq -} diff --git a/evm/go-x1/topicsdb/topicsdb_test.go b/evm/go-x1/topicsdb/topicsdb_test.go deleted file mode 100644 index 12ba545..0000000 --- a/evm/go-x1/topicsdb/topicsdb_test.go +++ /dev/null @@ -1,556 +0,0 @@ -package topicsdb - -import ( - "context" - "fmt" - "math/rand" - "os" - "runtime/debug" - "testing" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/go-opera/utils/dbutil/threads" -) - -func TestMain(m *testing.M) { - debug.SetMaxThreads(20) - - os.Exit(m.Run()) -} - -func newTestIndex() *index { - mem := threads.CountedDBProducer(memorydb.NewProducer("")) - return newIndex(mem) -} - -func TestIndexSearchMultyVariants(t *testing.T) { - logger.SetTestMode(t) - var ( - hash1 = common.BytesToHash([]byte("topic1")) - hash2 = common.BytesToHash([]byte("topic2")) - hash3 = common.BytesToHash([]byte("topic3")) - hash4 = common.BytesToHash([]byte("topic4")) - addr1 = randAddress() - addr2 = randAddress() - addr3 = randAddress() - addr4 = randAddress() - ) - testdata := []*types.Log{{ - BlockNumber: 1, - Address: addr1, - Topics: []common.Hash{hash1, hash1, hash1}, - }, { - BlockNumber: 3, - Address: addr2, - Topics: []common.Hash{hash2, hash2, hash2}, - }, { - BlockNumber: 998, - Address: addr3, - Topics: []common.Hash{hash3, hash3, hash3}, - }, { - BlockNumber: 999, - Address: addr4, - Topics: []common.Hash{hash4, hash4, hash4}, - }, - } - - index := newTestIndex() - - for _, l := range testdata { - err := index.Push(l) - require.NoError(t, err) - } - - // require.ElementsMatchf(testdata, got, "") doesn't work properly here, - // so use check() - check := func(require *require.Assertions, got []*types.Log) { - count := 0 - for _, a := range got { - for _, b := range testdata { - if b.Address == a.Address { - require.ElementsMatch(a.Topics, b.Topics) - count++ - break - } - } - } - } - - pooled := withThreadPool{index} - - for dsc, method := range map[string]func(context.Context, idx.Block, idx.Block, [][]common.Hash) ([]*types.Log, error){ - "index": index.FindInBlocks, - "pooled": pooled.FindInBlocks, - } { - t.Run(dsc, func(t *testing.T) { - - t.Run("With no addresses", func(t *testing.T) { - require := require.New(t) - got, err := method(nil, 0, 1000, [][]common.Hash{ - {}, - {hash1, hash2, hash3, hash4}, - {}, - {hash1, hash2, hash3, hash4}, - }) - require.NoError(err) - require.Equal(4, len(got)) - check(require, got) - }) - - t.Run("With addresses", func(t *testing.T) { - require := require.New(t) - got, err := method(nil, 0, 1000, [][]common.Hash{ - {addr1.Hash(), addr2.Hash(), addr3.Hash(), addr4.Hash()}, - {hash1, hash2, hash3, hash4}, - {}, - {hash1, hash2, hash3, hash4}, - }) - require.NoError(err) - require.Equal(4, len(got)) - check(require, got) - }) - - t.Run("With block range", func(t *testing.T) { - require := require.New(t) - got, err := method(nil, 2, 998, [][]common.Hash{ - {addr1.Hash(), addr2.Hash(), addr3.Hash(), addr4.Hash()}, - {hash1, hash2, hash3, hash4}, - {}, - {hash1, hash2, hash3, hash4}, - }) - require.NoError(err) - require.Equal(2, len(got)) - check(require, got) - }) - - t.Run("With addresses and blocks", func(t *testing.T) { - require := require.New(t) - - got1, err := method(nil, 2, 998, [][]common.Hash{ - {addr1.Hash(), addr2.Hash(), addr3.Hash(), addr4.Hash()}, - {hash1, hash2, hash3, hash4}, - {}, - {hash1, hash2, hash3, hash4}, - }) - require.NoError(err) - require.Equal(2, len(got1)) - check(require, got1) - - got2, err := method(nil, 2, 998, [][]common.Hash{ - {addr4.Hash(), addr3.Hash(), addr2.Hash(), addr1.Hash()}, - {hash1, hash2, hash3, hash4}, - {}, - {hash1, hash2, hash3, hash4}, - }) - require.NoError(err) - require.ElementsMatch(got1, got2) - }) - - }) - } -} - -func TestIndexSearchShortCircuits(t *testing.T) { - logger.SetTestMode(t) - var ( - hash1 = common.BytesToHash([]byte("topic1")) - hash2 = common.BytesToHash([]byte("topic2")) - hash3 = common.BytesToHash([]byte("topic3")) - hash4 = common.BytesToHash([]byte("topic4")) - addr1 = randAddress() - addr2 = randAddress() - ) - testdata := []*types.Log{{ - BlockNumber: 1, - Address: addr1, - Topics: []common.Hash{hash1, hash2}, - }, { - BlockNumber: 3, - Address: addr1, - Topics: []common.Hash{hash1, hash2, hash3}, - }, { - BlockNumber: 998, - Address: addr2, - Topics: []common.Hash{hash1, hash2, hash4}, - }, { - BlockNumber: 999, - Address: addr1, - Topics: []common.Hash{hash1, hash2, hash4}, - }, - } - - index := newTestIndex() - - for _, l := range testdata { - err := index.Push(l) - require.NoError(t, err) - } - - pooled := withThreadPool{index} - - for dsc, method := range map[string]func(context.Context, idx.Block, idx.Block, [][]common.Hash) ([]*types.Log, error){ - "index": index.FindInBlocks, - "pooled": pooled.FindInBlocks, - } { - t.Run(dsc, func(t *testing.T) { - - t.Run("topics count 1", func(t *testing.T) { - require := require.New(t) - got, err := method(nil, 0, 1000, [][]common.Hash{ - {addr1.Hash()}, - {}, - {}, - {hash3}, - }) - require.NoError(err) - require.Equal(1, len(got)) - }) - - t.Run("topics count 2", func(t *testing.T) { - require := require.New(t) - got, err := method(nil, 0, 1000, [][]common.Hash{ - {addr1.Hash()}, - {}, - {}, - {hash3, hash4}, - }) - require.NoError(err) - require.Equal(2, len(got)) - }) - - t.Run("block range", func(t *testing.T) { - require := require.New(t) - got, err := method(nil, 3, 998, [][]common.Hash{ - {addr1.Hash()}, - {}, - {}, - {hash3, hash4}, - }) - require.NoError(err) - require.Equal(1, len(got)) - }) - - }) - } -} - -func TestIndexSearchSingleVariant(t *testing.T) { - logger.SetTestMode(t) - - topics, recs, topics4rec := genTestData(100) - - index := newTestIndex() - - for _, rec := range recs { - err := index.Push(rec) - require.NoError(t, err) - } - - pooled := withThreadPool{index} - - for dsc, method := range map[string]func(context.Context, idx.Block, idx.Block, [][]common.Hash) ([]*types.Log, error){ - "index": index.FindInBlocks, - "pooled": pooled.FindInBlocks, - } { - t.Run(dsc, func(t *testing.T) { - require := require.New(t) - - for i := 0; i < len(topics); i++ { - from, to := topics4rec(i) - tt := topics[from : to-1] - - qq := make([][]common.Hash, len(tt)+1) - for pos, t := range tt { - qq[pos+1] = []common.Hash{t} - } - - got, err := method(nil, 0, 1000, qq) - require.NoError(err) - - var expect []*types.Log - for j, rec := range recs { - if f, t := topics4rec(j); f != from || t != to { - continue - } - expect = append(expect, rec) - } - - require.ElementsMatchf(expect, got, "step %d", i) - } - - }) - } -} - -func TestIndexSearchSimple(t *testing.T) { - logger.SetTestMode(t) - - var ( - hash1 = common.BytesToHash([]byte("topic1")) - hash2 = common.BytesToHash([]byte("topic2")) - hash3 = common.BytesToHash([]byte("topic3")) - hash4 = common.BytesToHash([]byte("topic4")) - addr = randAddress() - ) - testdata := []*types.Log{{ - BlockNumber: 1, - Address: addr, - Topics: []common.Hash{hash1}, - }, { - BlockNumber: 2, - Address: addr, - Topics: []common.Hash{hash2}, - }, { - BlockNumber: 998, - Address: addr, - Topics: []common.Hash{hash3}, - }, { - BlockNumber: 999, - Address: addr, - Topics: []common.Hash{hash4}, - }, - } - - index := newTestIndex() - - for _, l := range testdata { - err := index.Push(l) - require.NoError(t, err) - } - - var ( - got []*types.Log - err error - ) - - pooled := withThreadPool{index} - - for dsc, method := range map[string]func(context.Context, idx.Block, idx.Block, [][]common.Hash) ([]*types.Log, error){ - "index": index.FindInBlocks, - "pooled": pooled.FindInBlocks, - } { - t.Run(dsc, func(t *testing.T) { - require := require.New(t) - - got, err = method(nil, 0, 0xffffffff, [][]common.Hash{ - {addr.Hash()}, - {hash1}, - }) - require.NoError(err) - require.Equal(1, len(got)) - - got, err = method(nil, 0, 0xffffffff, [][]common.Hash{ - {addr.Hash()}, - {hash2}, - }) - require.NoError(err) - require.Equal(1, len(got)) - - got, err = method(nil, 0, 0xffffffff, [][]common.Hash{ - {addr.Hash()}, - {hash3}, - }) - require.NoError(err) - require.Equal(1, len(got)) - }) - } - -} - -func TestMaxTopicsCount(t *testing.T) { - logger.SetTestMode(t) - - testdata := &types.Log{ - BlockNumber: 1, - Address: randAddress(), - Topics: make([]common.Hash, maxTopicsCount), - } - pattern := make([][]common.Hash, maxTopicsCount+1) - pattern[0] = []common.Hash{testdata.Address.Hash()} - for i := range testdata.Topics { - testdata.Topics[i] = common.BytesToHash([]byte(fmt.Sprintf("topic%d", i))) - pattern[0] = append(pattern[0], testdata.Topics[i]) - pattern[i+1] = []common.Hash{testdata.Topics[i]} - } - - index := newTestIndex() - err := index.Push(testdata) - require.NoError(t, err) - - pooled := withThreadPool{index} - - for dsc, method := range map[string]func(context.Context, idx.Block, idx.Block, [][]common.Hash) ([]*types.Log, error){ - "index": index.FindInBlocks, - "pooled": pooled.FindInBlocks, - } { - t.Run(dsc, func(t *testing.T) { - require := require.New(t) - - got, err := method(nil, 0, 0xffffffff, pattern) - require.NoError(err) - require.Equal(1, len(got)) - require.Equal(maxTopicsCount, len(got[0].Topics)) - }) - } - - require.Equal(t, maxTopicsCount+1, len(pattern)) - require.Equal(t, maxTopicsCount+1, len(pattern[0])) -} - -func TestPatternLimit(t *testing.T) { - logger.SetTestMode(t) - require := require.New(t) - - data := []struct { - pattern [][]common.Hash - exp [][]common.Hash - err error - }{ - { - pattern: [][]common.Hash{}, - exp: [][]common.Hash{}, - err: ErrEmptyTopics, - }, - { - pattern: [][]common.Hash{[]common.Hash{}, []common.Hash{}, []common.Hash{}}, - exp: [][]common.Hash{[]common.Hash{}, []common.Hash{}, []common.Hash{}}, - err: ErrEmptyTopics, - }, - { - pattern: [][]common.Hash{ - []common.Hash{hash.FakeHash(1), hash.FakeHash(1)}, []common.Hash{hash.FakeHash(2), hash.FakeHash(2)}, []common.Hash{hash.FakeHash(3), hash.FakeHash(4)}}, - exp: [][]common.Hash{ - []common.Hash{hash.FakeHash(1)}, []common.Hash{hash.FakeHash(2)}, []common.Hash{hash.FakeHash(3), hash.FakeHash(4)}}, - err: nil, - }, - { - pattern: [][]common.Hash{ - []common.Hash{hash.FakeHash(1), hash.FakeHash(2)}, []common.Hash{hash.FakeHash(3), hash.FakeHash(4)}, []common.Hash{hash.FakeHash(5), hash.FakeHash(6)}}, - exp: [][]common.Hash{ - []common.Hash{hash.FakeHash(1), hash.FakeHash(2)}, []common.Hash{hash.FakeHash(3), hash.FakeHash(4)}, []common.Hash{hash.FakeHash(5), hash.FakeHash(6)}}, - err: nil, - }, - { - pattern: append(append(make([][]common.Hash, maxTopicsCount), []common.Hash{hash.FakeHash(1)}), []common.Hash{hash.FakeHash(1)}), - exp: append(make([][]common.Hash, maxTopicsCount), []common.Hash{hash.FakeHash(1)}), - err: nil, - }, - } - - for i, x := range data { - got, err := limitPattern(x.pattern) - require.Equal(len(x.exp), len(got)) - for j := range got { - require.ElementsMatch(x.exp[j], got[j], i, j) - } - require.Equal(x.err, err, i) - } -} - -func TestKvdbThreadsPoolLimit(t *testing.T) { - logger.SetTestMode(t) - - const N = 100 - - _, recs, _ := genTestData(N) - index := newTestIndex() - for _, rec := range recs { - err := index.Push(rec) - require.NoError(t, err) - } - - pooled := withThreadPool{index} - - for dsc, method := range map[string]func(context.Context, idx.Block, idx.Block, [][]common.Hash) ([]*types.Log, error){ - "index": index.FindInBlocks, - "pooled": pooled.FindInBlocks, - } { - t.Run(dsc, func(t *testing.T) { - require := require.New(t) - - topics := make([]common.Hash, threads.GlobalPool.Cap()+1) - for i := range topics { - topics[i] = hash.FakeHash(int64(i)) - } - require.Less(threads.GlobalPool.Cap(), len(topics)) - qq := make([][]common.Hash, 3) - - // one big pattern - qq[1] = topics - got, err := method(nil, 0, 1000, qq) - require.NoError(err) - require.Equal(N, len(got)) - - // more than one big pattern - qq[1], qq[2] = topics, topics - got, err = method(nil, 0, 1000, qq) - switch dsc { - case "index": - require.NoError(err) - require.Equal(N, len(got)) - case "pooled": - require.Equal(ErrTooBigTopics, err) - require.Equal(0, len(got)) - - } - - }) - } -} - -func genTestData(count int) ( - topics []common.Hash, - recs []*types.Log, - topics4rec func(rec int) (from, to int), -) { - const ( - period = 5 - ) - - topics = make([]common.Hash, period) - for i := range topics { - topics[i] = hash.FakeHash(int64(i)) - } - - topics4rec = func(rec int) (from, to int) { - from = rec % (period - 3) - to = from + 3 - return - } - - recs = make([]*types.Log, count) - for i := range recs { - from, to := topics4rec(i) - r := &types.Log{ - BlockNumber: uint64(i / period), - BlockHash: hash.FakeHash(int64(i / period)), - TxHash: hash.FakeHash(int64(i % period)), - Index: uint(i % period), - Address: randAddress(), - Topics: topics[from:to], - Data: make([]byte, i), - } - _, _ = rand.Read(r.Data) - recs[i] = r - } - - return -} - -func randAddress() (addr common.Address) { - n, err := rand.Read(addr[:]) - if err != nil { - panic(err) - } - if n != common.AddressLength { - panic("address is not filled") - } - return -} diff --git a/evm/go-x1/tracing/tx-tracing.go b/evm/go-x1/tracing/tx-tracing.go deleted file mode 100644 index d037e18..0000000 --- a/evm/go-x1/tracing/tx-tracing.go +++ /dev/null @@ -1,80 +0,0 @@ -package tracing - -import ( - "sync" - - "github.com/ethereum/go-ethereum/common" - "github.com/opentracing/opentracing-go" -) - -var ( - enabled bool - txSpans = make(map[common.Hash]opentracing.Span) - txSpansMu sync.RWMutex - - noopSpan = opentracing.NoopTracer{}.StartSpan("") -) - -func SetEnabled(val bool) { - enabled = val -} - -func Enabled() bool { - return enabled -} - -func StartTx(tx common.Hash, operation string) { - if !enabled { - return - } - - txSpansMu.Lock() - defer txSpansMu.Unlock() - - if _, ok := txSpans[tx]; ok { - return - } - - span := opentracing.StartSpan("lifecycle") - span.SetTag("txhash", tx.String()) - span.SetTag("enter", operation) - txSpans[tx] = span -} - -func FinishTx(tx common.Hash, operation string) { - if !enabled { - return - } - - txSpansMu.Lock() - defer txSpansMu.Unlock() - - span, ok := txSpans[tx] - if !ok { - return - } - - span.SetTag("exit", operation) - span.Finish() - delete(txSpans, tx) -} - -func CheckTx(tx common.Hash, operation string) opentracing.Span { - if !enabled { - return noopSpan - } - - txSpansMu.RLock() - defer txSpansMu.RUnlock() - - span, ok := txSpans[tx] - - if !ok { - return noopSpan - } - - return opentracing.GlobalTracer().StartSpan( - operation, - opentracing.ChildOf(span.Context()), - ) -} diff --git a/evm/go-x1/utils/adapters/ethdb2kvdb/adapter.go b/evm/go-x1/utils/adapters/ethdb2kvdb/adapter.go deleted file mode 100644 index d585cf3..0000000 --- a/evm/go-x1/utils/adapters/ethdb2kvdb/adapter.go +++ /dev/null @@ -1,49 +0,0 @@ -package ethdb2kvdb - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/ethdb" -) - -type Adapter struct { - ethdb.KeyValueStore -} - -var _ kvdb.Store = (*Adapter)(nil) - -func Wrap(v ethdb.KeyValueStore) *Adapter { - return &Adapter{v} -} - -func (db *Adapter) Drop() { - panic("called Drop on ethdb") -} - -// batch is a write-only memory batch that commits changes to its host -// database when Write is called. A batch cannot be used concurrently. -type batch struct { - ethdb.Batch -} - -// Replay replays the batch contents. -func (b *batch) Replay(w kvdb.Writer) error { - return b.Batch.Replay(w) -} - -// NewBatch creates a write-only key-value store that buffers changes to its host -// database until a final write is called. -func (db *Adapter) NewBatch() kvdb.Batch { - return &batch{db.KeyValueStore.NewBatch()} -} - -func (db *Adapter) GetSnapshot() (kvdb.Snapshot, error) { - panic("called GetSnapshot on ethdb") - return nil, nil -} - -// NewIterator creates a binary-alphabetical iterator over a subset -// of database content with a particular key prefix, starting at a particular -// initial key (or after, if it does not exist). -func (db *Adapter) NewIterator(prefix []byte, start []byte) kvdb.Iterator { - return db.KeyValueStore.NewIterator(prefix, start) -} diff --git a/evm/go-x1/utils/adapters/kvdb2ethdb/adapter.go b/evm/go-x1/utils/adapters/kvdb2ethdb/adapter.go deleted file mode 100644 index 21dd2d4..0000000 --- a/evm/go-x1/utils/adapters/kvdb2ethdb/adapter.go +++ /dev/null @@ -1,40 +0,0 @@ -package kvdb2ethdb - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/ethdb" -) - -type Adapter struct { - kvdb.Store -} - -var _ ethdb.KeyValueStore = (*Adapter)(nil) - -func Wrap(v kvdb.Store) *Adapter { - return &Adapter{v} -} - -// batch is a write-only memory batch that commits changes to its host -// database when Write is called. A batch cannot be used concurrently. -type batch struct { - kvdb.Batch -} - -// Replay replays the batch contents. -func (b *batch) Replay(w ethdb.KeyValueWriter) error { - return b.Batch.Replay(w) -} - -// NewBatch creates a write-only key-value store that buffers changes to its host -// database until a final write is called. -func (db *Adapter) NewBatch() ethdb.Batch { - return &batch{db.Store.NewBatch()} -} - -// NewIterator creates a binary-alphabetical iterator over a subset -// of database content with a particular key prefix, starting at a particular -// initial key (or after, if it does not exist). -func (db *Adapter) NewIterator(prefix []byte, start []byte) ethdb.Iterator { - return db.Store.NewIterator(prefix, start) -} diff --git a/evm/go-x1/utils/adapters/snap2kvdb/adapter.go b/evm/go-x1/utils/adapters/snap2kvdb/adapter.go deleted file mode 100644 index 00d5944..0000000 --- a/evm/go-x1/utils/adapters/snap2kvdb/adapter.go +++ /dev/null @@ -1,50 +0,0 @@ -package snap2kvdb - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/devnulldb" - "github.com/ethereum/go-ethereum/log" -) - -type Adapter struct { - kvdb.Snapshot -} - -var _ kvdb.Store = (*Adapter)(nil) - -func Wrap(v kvdb.Snapshot) *Adapter { - return &Adapter{v} -} - -func (db *Adapter) Put(key []byte, value []byte) error { - log.Warn("called Put on snapshot") - return nil -} - -func (db *Adapter) Delete(key []byte) error { - log.Warn("called Delete on snapshot") - return nil -} - -func (db *Adapter) GetSnapshot() (kvdb.Snapshot, error) { - return db.Snapshot, nil -} - -func (db *Adapter) NewBatch() kvdb.Batch { - log.Warn("called NewBatch on snapshot") - return devnulldb.New().NewBatch() -} - -func (db *Adapter) Compact(start []byte, limit []byte) error { - return nil -} - -func (db *Adapter) Close() error { - return nil -} - -func (db *Adapter) Drop() {} - -func (db *Adapter) Stat(property string) (string, error) { - return "", nil -} diff --git a/evm/go-x1/utils/adapters/vecmt2dagidx/vecmt2lachesis.go b/evm/go-x1/utils/adapters/vecmt2dagidx/vecmt2lachesis.go deleted file mode 100644 index 641d083..0000000 --- a/evm/go-x1/utils/adapters/vecmt2dagidx/vecmt2lachesis.go +++ /dev/null @@ -1,54 +0,0 @@ -package vecmt2dagidx - -import ( - "github.com/Fantom-foundation/lachesis-base/abft" - "github.com/Fantom-foundation/lachesis-base/abft/dagidx" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/vecfc" - - "github.com/Fantom-foundation/go-opera/vecmt" -) - -type Adapter struct { - *vecmt.Index -} - -var _ abft.DagIndex = (*Adapter)(nil) - -type AdapterSeq struct { - *vecmt.HighestBefore -} - -type BranchSeq struct { - vecfc.BranchSeq -} - -// Seq is a maximum observed e.Seq in the branch -func (b *BranchSeq) Seq() idx.Event { - return b.BranchSeq.Seq -} - -// MinSeq is a minimum observed e.Seq in the branch -func (b *BranchSeq) MinSeq() idx.Event { - return b.BranchSeq.MinSeq -} - -// Size of the vector clock -func (b AdapterSeq) Size() int { - return b.VSeq.Size() -} - -// Get i's position in the byte-encoded vector clock -func (b AdapterSeq) Get(i idx.Validator) dagidx.Seq { - seq := b.HighestBefore.VSeq.Get(i) - return &BranchSeq{seq} -} - -func (v *Adapter) GetMergedHighestBefore(id hash.Event) dagidx.HighestBeforeSeq { - return AdapterSeq{v.Index.GetMergedHighestBefore(id)} -} - -func Wrap(v *vecmt.Index) *Adapter { - return &Adapter{v} -} diff --git a/evm/go-x1/utils/bitmap/bitset.go b/evm/go-x1/utils/bitmap/bitset.go deleted file mode 100644 index 58f3f74..0000000 --- a/evm/go-x1/utils/bitmap/bitset.go +++ /dev/null @@ -1,29 +0,0 @@ -package bitmap - -type Set []byte - -func New(max int) Set { - l := max / 8 - if max%8 != 0 { - l++ - } - return make(Set, l) -} - -func (s Set) Put(i int) { - yi := i / 8 - bi := i % 8 - s[yi] |= 1 << bi -} - -func (s Set) Del(i int) { - yi := i / 8 - bi := i % 8 - s[yi] &= ^(1 << bi) -} - -func (s Set) Has(i int) bool { - yi := i / 8 - bi := i % 8 - return (s[yi] & (1 << bi)) != 0 -} diff --git a/evm/go-x1/utils/bits/bits.go b/evm/go-x1/utils/bits/bits.go deleted file mode 100644 index 1e8bbcc..0000000 --- a/evm/go-x1/utils/bits/bits.go +++ /dev/null @@ -1,130 +0,0 @@ -package bits - -type ( - // Array is a bitmap array - Array struct { - Bytes []byte - } - - // Writer of numbers to Array. - Writer struct { - *Array - bitOffset int - } - - // Reader of numbers from Array. - Reader struct { - *Array - byteOffset int - bitOffset int - } -) - -// NewWriter is a bitmap writer -func NewWriter(arr *Array) *Writer { - return &Writer{ - Array: arr, - } -} - -// NewReader is a bitmap reader -func NewReader(arr *Array) *Reader { - return &Reader{ - Array: arr, - } -} - -func (a *Writer) byteBitsFree() int { - return 8 - a.bitOffset -} - -func (a *Writer) writeIntoLastByte(v uint) { - a.Bytes[len(a.Bytes)-1] |= byte(v << a.bitOffset) -} - -func zeroTopByteBits(v uint, bits int) uint { - mask := uint(0xff) >> bits - return v & mask -} - -// Write bits of a number into array. -func (a *Writer) Write(bits int, v uint) { - if a.bitOffset == 0 { - a.Bytes = append(a.Bytes, byte(0)) - } - free := a.byteBitsFree() - if bits <= free { - toWrite := bits - // appending v to the bit array - a.writeIntoLastByte(v) - // increment offsets - if toWrite == free { - a.bitOffset = 0 - } else { - a.bitOffset += toWrite - } - } else { - toWrite := free - clear := a.bitOffset // 8 - free - // zeroing top `clear` bits and appending result to the bit array - a.writeIntoLastByte(zeroTopByteBits(v, clear)) - // increment offsets - a.bitOffset = 0 - a.Write(bits-toWrite, v>>toWrite) - } -} - -func (a *Reader) byteBitsFree() int { - return 8 - a.bitOffset -} - -func (a *Reader) Read(bits int) (v uint) { - // perform all the checks in the same function to make CPU branch predictor work better - if bits == 0 { - return 0 - } - /*if bits > a.NonReadBits() { - panic(io.ErrUnexpectedEOF) - }*/ - - free := a.byteBitsFree() - if bits <= free { - toRead := bits - clear := 8 - (a.bitOffset + toRead) - v = zeroTopByteBits(uint(a.Bytes[a.byteOffset]), clear) >> a.bitOffset - // increment offsets - if toRead == free { - a.bitOffset = 0 - a.byteOffset++ - } else { - a.bitOffset += toRead - } - } else { - toRead := free - v = uint(a.Bytes[a.byteOffset]) >> a.bitOffset - // increment offsets - a.bitOffset = 0 - a.byteOffset++ - // read rest - rest := a.Read(bits - toRead) - v |= rest << toRead - } - return -} - -func (a *Reader) View(bits int) (v uint) { - cp := *a - cpp := &cp - return cpp.Read(bits) -} - -// NonReadBytes returns a number of non-consumed bytes -func (a *Reader) NonReadBytes() int { - return len(a.Bytes) - a.byteOffset -} - -// NonReadBytes returns a number of non-consumed bits -func (a *Reader) NonReadBits() int { - //return a.nonReadBits - return a.NonReadBytes()*8 - a.bitOffset -} diff --git a/evm/go-x1/utils/bits/bits_test.go b/evm/go-x1/utils/bits/bits_test.go deleted file mode 100644 index 4096068..0000000 --- a/evm/go-x1/utils/bits/bits_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package bits - -import ( - "fmt" - "math/rand" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestBitArrayEmpty(t *testing.T) { - testBitArray(t, []testWord{}, "empty") -} - -func TestBitArrayB0(t *testing.T) { - testBitArray(t, []testWord{ - {1, 0b0}, - }, "b0") -} - -func TestBitArrayB1(t *testing.T) { - testBitArray(t, []testWord{ - {1, 0b1}, - }, "b1") -} - -func TestBitArrayB010101010(t *testing.T) { - testBitArray(t, []testWord{ - {9, 0b010101010}, - }, "b010101010") -} - -func TestBitArrayV01010101010101010(t *testing.T) { - testBitArray(t, []testWord{ - {17, 0b01010101010101010}, - }, "b01010101010101010") -} - -func TestBitArrayRand1(t *testing.T) { - r := rand.New(rand.NewSource(0)) - for i := 0; i < 50; i++ { - testBitArray(t, genTestWords(r, 24, 1), fmt.Sprintf("1 bit, case#%d", i)) - } -} - -func TestBitArrayRand8(t *testing.T) { - r := rand.New(rand.NewSource(0)) - for i := 0; i < 50; i++ { - testBitArray(t, genTestWords(r, 100, 8), fmt.Sprintf("8 bits, case#%d", i)) - } -} - -func TestBitArrayRand17(t *testing.T) { - r := rand.New(rand.NewSource(0)) - for i := 0; i < 50; i++ { - testBitArray(t, genTestWords(r, 50, 17), fmt.Sprintf("17 bits, case#%d", i)) - } -} - -func genTestWords(r *rand.Rand, maxCount int, maxBits int) []testWord { - count := r.Intn(maxCount) - words := make([]testWord, count) - for i := range words { - if maxBits == 1 { - words[i].bits = 1 - } else { - words[i].bits = 1 + r.Intn(maxBits-1) - } - words[i].v = uint(r.Intn(1 << words[i].bits)) - } - return words -} - -func bytesToFit(bits int) int { - if bits%8 == 0 { - return bits / 8 - } - return bits/8 + 1 -} - -type testWord struct { - bits int - v uint -} - -func testBitArray(t *testing.T, words []testWord, name string) { - arr := Array{make([]byte, 0, 100)} - writer := NewWriter(&arr) - reader := NewReader(&arr) - - totalBitsWritten := 0 - for _, w := range words { - writer.Write(w.bits, w.v) - totalBitsWritten += w.bits - } - assert.EqualValuesf(t, bytesToFit(totalBitsWritten), len(arr.Bytes), name) - - totalBitsRead := 0 - for _, w := range words { - assert.EqualValuesf(t, bytesToFit(totalBitsWritten)*8-totalBitsRead, reader.NonReadBits(), name) - assert.EqualValuesf(t, bytesToFit(reader.NonReadBits()), reader.NonReadBytes(), name) - - v := reader.Read(w.bits) - assert.EqualValuesf(t, w.v, v, name) - totalBitsRead += w.bits - - assert.EqualValuesf(t, bytesToFit(totalBitsWritten)*8-totalBitsRead, reader.NonReadBits(), name) - assert.EqualValuesf(t, bytesToFit(reader.NonReadBits()), reader.NonReadBytes(), name) - } - - // read the tail - assert.Panicsf(t, func() { - reader.Read(reader.NonReadBits() + 1) - }, name) - zero := reader.Read(reader.NonReadBits()) - assert.EqualValuesf(t, uint(0), zero, name) - assert.EqualValuesf(t, int(0), reader.NonReadBits(), name) - assert.EqualValuesf(t, int(0), reader.NonReadBytes(), name) -} - -func BenchmarkArray_write(b *testing.B) { - for bits := 1; bits <= 9; bits++ { - b.Run(fmt.Sprintf("%d bits", bits), func(b *testing.B) { - b.ResetTimer() - - arr := Array{make([]byte, 0, bytesToFit(bits*b.N))} - writer := NewWriter(&arr) - for i := 0; i < b.N; i++ { - writer.Write(bits, 0xff) - } - }) - } -} - -func BenchmarkArray_read(b *testing.B) { - for bits := 1; bits <= 9; bits++ { - b.Run(fmt.Sprintf("%d bits", bits), func(b *testing.B) { - b.ResetTimer() - - arr := Array{make([]byte, bytesToFit(bits*b.N))} - writer := NewReader(&arr) - for i := 0; i < b.N; i++ { - _ = writer.Read(bits) - } - }) - } -} diff --git a/evm/go-x1/utils/concurrent/ValidatorBlocksSet.go b/evm/go-x1/utils/concurrent/ValidatorBlocksSet.go deleted file mode 100644 index e323e06..0000000 --- a/evm/go-x1/utils/concurrent/ValidatorBlocksSet.go +++ /dev/null @@ -1,19 +0,0 @@ -package concurrent - -import ( - "sync" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -type ValidatorBlocksSet struct { - sync.RWMutex - Val map[idx.ValidatorID]idx.Block -} - -func WrapValidatorBlocksSet(v map[idx.ValidatorID]idx.Block) *ValidatorBlocksSet { - return &ValidatorBlocksSet{ - RWMutex: sync.RWMutex{}, - Val: v, - } -} diff --git a/evm/go-x1/utils/concurrent/ValidatorEpochsSet.go b/evm/go-x1/utils/concurrent/ValidatorEpochsSet.go deleted file mode 100644 index 9209bd5..0000000 --- a/evm/go-x1/utils/concurrent/ValidatorEpochsSet.go +++ /dev/null @@ -1,19 +0,0 @@ -package concurrent - -import ( - "sync" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -type ValidatorEpochsSet struct { - sync.RWMutex - Val map[idx.ValidatorID]idx.Epoch -} - -func WrapValidatorEpochsSet(v map[idx.ValidatorID]idx.Epoch) *ValidatorEpochsSet { - return &ValidatorEpochsSet{ - RWMutex: sync.RWMutex{}, - Val: v, - } -} diff --git a/evm/go-x1/utils/concurrent/ValidatorEventsSet.go b/evm/go-x1/utils/concurrent/ValidatorEventsSet.go deleted file mode 100644 index 8ed1582..0000000 --- a/evm/go-x1/utils/concurrent/ValidatorEventsSet.go +++ /dev/null @@ -1,20 +0,0 @@ -package concurrent - -import ( - "sync" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -type ValidatorEventsSet struct { - sync.RWMutex - Val map[idx.ValidatorID]hash.Event -} - -func WrapValidatorEventsSet(v map[idx.ValidatorID]hash.Event) *ValidatorEventsSet { - return &ValidatorEventsSet{ - RWMutex: sync.RWMutex{}, - Val: v, - } -} diff --git a/evm/go-x1/utils/concurrent/events.go b/evm/go-x1/utils/concurrent/events.go deleted file mode 100644 index e2bec39..0000000 --- a/evm/go-x1/utils/concurrent/events.go +++ /dev/null @@ -1,19 +0,0 @@ -package concurrent - -import ( - "sync" - - "github.com/Fantom-foundation/lachesis-base/hash" -) - -type EventsSet struct { - sync.RWMutex - Val hash.EventsSet -} - -func WrapEventsSet(v hash.EventsSet) *EventsSet { - return &EventsSet{ - RWMutex: sync.RWMutex{}, - Val: v, - } -} diff --git a/evm/go-x1/utils/cser/binary.go b/evm/go-x1/utils/cser/binary.go deleted file mode 100644 index 5fd7f48..0000000 --- a/evm/go-x1/utils/cser/binary.go +++ /dev/null @@ -1,96 +0,0 @@ -package cser - -import ( - "github.com/Fantom-foundation/go-opera/utils/bits" - "github.com/Fantom-foundation/go-opera/utils/fast" -) - -func MarshalBinaryAdapter(marshalCser func(*Writer) error) ([]byte, error) { - w := NewWriter() - err := marshalCser(w) - if err != nil { - return nil, err - } - - return binaryFromCSER(w.BitsW.Array, w.BytesW.Bytes()) -} - -// binaryFromCSER packs body bytes and bits into raw -func binaryFromCSER(bbits *bits.Array, bbytes []byte) (raw []byte, err error) { - bodyBytes := fast.NewWriter(bbytes) - bodyBytes.Write(bbits.Bytes) - // write bits size - sizeWriter := fast.NewWriter(make([]byte, 0, 4)) - writeUint64Compact(sizeWriter, uint64(len(bbits.Bytes))) - bodyBytes.Write(reversed(sizeWriter.Bytes())) - return bodyBytes.Bytes(), nil -} - -// binaryToCSER unpacks raw on body bytes and bits -func binaryToCSER(raw []byte) (bbits *bits.Array, bbytes []byte, err error) { - // read bitsArray size - bitsSizeBuf := reversed(tail(raw, 9)) - bitsSizeReader := fast.NewReader(bitsSizeBuf) - bitsSize := readUint64Compact(bitsSizeReader) - raw = raw[:len(raw)-bitsSizeReader.Position()] - - if uint64(len(raw)) < bitsSize { - err = ErrMalformedEncoding - return - } - - bbits = &bits.Array{Bytes: raw[uint64(len(raw))-bitsSize:]} - bbytes = raw[:uint64(len(raw))-bitsSize] - return -} - -func UnmarshalBinaryAdapter(raw []byte, unmarshalCser func(reader *Reader) error) (err error) { - defer func() { - if r := recover(); r != nil { - err = ErrMalformedEncoding - } - }() - - bbits, bbytes, err := binaryToCSER(raw) - if err != nil { - return err - } - - bodyReader := &Reader{ - BitsR: bits.NewReader(bbits), - BytesR: fast.NewReader(bbytes), - } - err = unmarshalCser(bodyReader) - if err != nil { - return err - } - - // check that everything is read - if bodyReader.BitsR.NonReadBytes() > 1 { - return ErrNonCanonicalEncoding - } - tail := bodyReader.BitsR.Read(bodyReader.BitsR.NonReadBits()) - if tail != 0 { - return ErrNonCanonicalEncoding - } - if !bodyReader.BytesR.Empty() { - return ErrNonCanonicalEncoding - } - - return nil -} - -func tail(b []byte, cap int) []byte { - if len(b) > cap { - return b[len(b)-cap:] - } - return b -} - -func reversed(b []byte) []byte { - reversed := make([]byte, len(b)) - for i, v := range b { - reversed[len(b)-1-i] = v - } - return reversed -} diff --git a/evm/go-x1/utils/cser/binary_test.go b/evm/go-x1/utils/cser/binary_test.go deleted file mode 100644 index b6fc7be..0000000 --- a/evm/go-x1/utils/cser/binary_test.go +++ /dev/null @@ -1,337 +0,0 @@ -package cser - -import ( - "errors" - "math" - "math/big" - "math/rand" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/utils/fast" -) - -func TestEmpty(t *testing.T) { - var ( - buf []byte - err error - ) - - t.Run("Write", func(t *testing.T) { - buf, err = MarshalBinaryAdapter(func(w *Writer) error { - return nil - }) - require.NoError(t, err) - }) - - t.Run("Read", func(t *testing.T) { - err = UnmarshalBinaryAdapter(buf, func(r *Reader) error { - return nil - }) - require.NoError(t, err) - }) -} - -func TestErr(t *testing.T) { - var ( - buf []byte - ) - - bufCopy := func() []byte { - bb := make([]byte, len(buf)) - copy(bb, buf) - return bb - } - - t.Run("Write", func(t *testing.T) { - require := require.New(t) - - bb, err := MarshalBinaryAdapter(func(w *Writer) error { - w.U64(math.MaxUint64) - return nil - }) - require.NoError(err) - buf = append(buf, bb...) - - errExp := errors.New("custom") - bb, err = MarshalBinaryAdapter(func(w *Writer) error { - w.Bool(false) - return errExp - }) - require.Equal(errExp, err) - buf = append(buf, bb...) - }) - - t.Run("Read nil", func(t *testing.T) { - require := require.New(t) - // nothing unmarshal - err := UnmarshalBinaryAdapter(nil, func(r *Reader) error { - return nil - }) - require.Equal(ErrMalformedEncoding, err) - }) - - t.Run("Read err", func(t *testing.T) { - require := require.New(t) - - errExp := errors.New("custom") - // unmarshal - err := UnmarshalBinaryAdapter(buf, func(r *Reader) error { - require.Equal(uint64(math.MaxUint64), r.U64()) - return errExp - }) - require.Equal(errExp, err) - }) - - t.Run("Read 0", func(t *testing.T) { - require := require.New(t) - // unpack - _, bbytes, err := binaryToCSER(bufCopy()) - require.NoError(err) - // pack with wrong bits size - corrupted := fast.NewWriter(bbytes) - sizeWriter := fast.NewWriter(make([]byte, 0, 4)) - writeUint64Compact(sizeWriter, uint64(len(bbytes)+1)) - corrupted.Write(reversed(sizeWriter.Bytes())) - // corrupted unpack - _, _, err = binaryToCSER(corrupted.Bytes()) - require.Equal(ErrMalformedEncoding, err) - // corrupted unmarshal - err = UnmarshalBinaryAdapter(corrupted.Bytes(), func(r *Reader) error { - require.Equal(uint64(math.MaxUint64), r.U64()) - return nil - }) - require.Equal(ErrMalformedEncoding, err) - }) - - repackWithDefect := func( - defect func(bbits, bbytes *[]byte) (expected error), - ) func(t *testing.T) { - return func(t *testing.T) { - require := require.New(t) - // unpack - bbits, bbytes, err := binaryToCSER(bufCopy()) - require.NoError(err) - // pack with defect - errExp := defect(&bbits.Bytes, &bbytes) - corrupted, err := binaryFromCSER(bbits, bbytes) - require.NoError(err) - // corrupted unmarshal - err = UnmarshalBinaryAdapter(corrupted, func(r *Reader) error { - _ = r.U64() - return nil - }) - require.Equal(errExp, err) - } - } - - t.Run("Read 1", repackWithDefect(func(bbits, bbytes *[]byte) (expected error) { - // no defect - return nil - })) - - t.Run("Read 2", repackWithDefect(func(bbits, bbytes *[]byte) (expected error) { - *bbytes = append(*bbytes, 0xFF) - return ErrNonCanonicalEncoding - })) - - t.Run("Read 3", repackWithDefect(func(bbits, bbytes *[]byte) (expected error) { - *bbits = append(*bbits, 0x0F) - return ErrNonCanonicalEncoding - })) - - t.Run("Read 4", repackWithDefect(func(bbits, bbytes *[]byte) (expected error) { - *bbytes = (*bbytes)[:len(*bbytes)-1] - return ErrNonCanonicalEncoding - })) -} - -func TestVals(t *testing.T) { - var ( - buf []byte - err error - ) - var ( - expBigInt = []*big.Int{big.NewInt(0), big.NewInt(0xFFFFF)} - expBool = []bool{true, false} - expFixedBytes = [][]byte{[]byte{}, randBytes(0xFF)} - expSliceBytes = [][]byte{[]byte{}, randBytes(0xFF)} - expU8 = []uint8{0, 1, 0xFF} - expU16 = []uint16{0, 1, 0xFFFF} - expU32 = []uint32{0, 1, 0xFFFFFFFF} - expU64 = []uint64{0, 1, 0xFFFFFFFFFFFFFFFF} - expVarUint = []uint64{0, 1, 0xFFFFFFFFFFFFFFFF} - expI64 = []int64{0, 1, math.MinInt64, math.MaxInt64} - expU56 = []uint64{0, 1, 1<<(8*7) - 1} - ) - - t.Run("Write", func(t *testing.T) { - require := require.New(t) - - buf, err = MarshalBinaryAdapter(func(w *Writer) error { - for _, v := range expBigInt { - w.BigInt(v) - } - for _, v := range expBool { - w.Bool(v) - } - for _, v := range expFixedBytes { - w.FixedBytes(v) - } - for _, v := range expSliceBytes { - w.SliceBytes(v) - } - for _, v := range expU8 { - w.U8(v) - } - for _, v := range expU16 { - w.U16(v) - } - for _, v := range expU32 { - w.U32(v) - } - for _, v := range expU64 { - w.U64(v) - } - for _, v := range expVarUint { - w.VarUint(v) - } - for _, v := range expI64 { - w.I64(v) - } - for _, v := range expU56 { - w.U56(v) - } - return nil - }) - require.NoError(err) - }) - - t.Run("Read", func(t *testing.T) { - require := require.New(t) - - err = UnmarshalBinaryAdapter(buf, func(r *Reader) error { - for i, exp := range expBigInt { - got := r.BigInt() - require.Equal(exp, got, i) - } - for i, exp := range expBool { - got := r.Bool() - require.Equal(exp, got, i) - } - for i, exp := range expFixedBytes { - got := make([]byte, len(exp)) - r.FixedBytes(got) - require.Equal(exp, got, i) - } - for i, exp := range expSliceBytes { - got := r.SliceBytes(255) - require.Equal(exp, got, i) - } - for i, exp := range expU8 { - got := r.U8() - require.Equal(exp, got, i) - } - for i, exp := range expU16 { - got := r.U16() - require.Equal(exp, got, i) - } - for i, exp := range expU32 { - got := r.U32() - require.Equal(exp, got, i) - } - for i, exp := range expU64 { - got := r.U64() - require.Equal(exp, got, i) - } - for i, exp := range expVarUint { - got := r.VarUint() - require.Equal(exp, got, i) - } - for i, exp := range expI64 { - got := r.I64() - require.Equal(exp, got, i) - } - for i, exp := range expU56 { - got := r.U56() - require.Equal(exp, got, i) - } - return nil - }) - require.NoError(err) - }) -} - -func TestBadVals(t *testing.T) { - var ( - buf []byte - err error - ) - var ( - expBigInt = []*big.Int{nil} - expFixedBytes = [][]byte{nil} - expSliceBytes = [][]byte{nil} - expU56 = []uint64{1 << (8 * 7), math.MaxUint64} - ) - - t.Run("Write", func(t *testing.T) { - require := require.New(t) - - buf, err = MarshalBinaryAdapter(func(w *Writer) error { - for _, v := range expBigInt { - require.Panics(func() { - w.BigInt(v) - }) - } - for _, v := range expFixedBytes { - w.FixedBytes(v) - } - for _, v := range expSliceBytes { - w.SliceBytes(v) - } - for _, v := range expU56 { - require.Panics(func() { - w.U56(v) - }) - } - return nil - }) - require.NoError(err) - }) - - t.Run("Read", func(t *testing.T) { - require := require.New(t) - - err = UnmarshalBinaryAdapter(buf, func(r *Reader) error { - for _, _ = range expBigInt { - // skip - } - for i, exp := range expFixedBytes { - got := make([]byte, len(exp)) - r.FixedBytes(got) - require.NotEqual(exp, got, i) - require.Equal(len(exp), len(got), i) - } - for i, exp := range expSliceBytes { - got := r.SliceBytes(1) - require.NotEqual(exp, got, i) - require.Equal(len(exp), len(got), i) - } - for _, _ = range expU56 { - // skip - } - return nil - }) - require.NoError(err) - }) -} - -func randBytes(n int) []byte { - bb := make([]byte, n) - _, err := rand.Read(bb) - if err != nil { - panic(err) - } - return bb -} diff --git a/evm/go-x1/utils/cser/read_writer.go b/evm/go-x1/utils/cser/read_writer.go deleted file mode 100644 index b4486cc..0000000 --- a/evm/go-x1/utils/cser/read_writer.go +++ /dev/null @@ -1,250 +0,0 @@ -package cser - -import ( - "errors" - "math/big" - - "github.com/Fantom-foundation/go-opera/utils/bits" - "github.com/Fantom-foundation/go-opera/utils/fast" -) - -var ( - ErrNonCanonicalEncoding = errors.New("non canonical encoding") - ErrMalformedEncoding = errors.New("malformed encoding") - ErrTooLargeAlloc = errors.New("too large allocation") -) - -const MaxAlloc = 100 * 1024 - -type Writer struct { - BitsW *bits.Writer - BytesW *fast.Writer -} - -type Reader struct { - BitsR *bits.Reader - BytesR *fast.Reader -} - -func NewWriter() *Writer { - bbits := &bits.Array{Bytes: make([]byte, 0, 32)} - bbytes := make([]byte, 0, 200) - return &Writer{ - BitsW: bits.NewWriter(bbits), - BytesW: fast.NewWriter(bbytes), - } -} - -func writeUint64Compact(bytesW *fast.Writer, v uint64) { - for i := 0; ; i++ { - chunk := v & 0b01111111 - v = v >> 7 - if v == 0 { - // stop flag - chunk |= 0b10000000 - } - bytesW.WriteByte(byte(chunk)) - if v == 0 { - break - } - } - return -} - -func readUint64Compact(bytesR *fast.Reader) uint64 { - v := uint64(0) - stop := false - for i := 0; !stop; i++ { - chunk := uint64(bytesR.ReadByte()) - stop = (chunk & 0b10000000) != 0 - word := chunk & 0b01111111 - v |= word << (i * 7) - // last byte cannot be zero - if i > 0 && stop && word == 0 { - panic(ErrNonCanonicalEncoding) - } - } - - return v -} - -func writeUint64BitCompact(bytesW *fast.Writer, v uint64, minSize int) (size int) { - for size < minSize || v != 0 { - bytesW.WriteByte(byte(v)) - size++ - v = v >> 8 - } - return -} - -func readUint64BitCompact(bytesR *fast.Reader, size int) uint64 { - var ( - v uint64 - last byte - ) - buf := bytesR.Read(size) - for i, b := range buf { - v |= uint64(b) << uint(8*i) - last = b - } - - if size > 1 && last == 0 { - panic(ErrNonCanonicalEncoding) - } - - return v -} - -func (r *Reader) U8() uint8 { - return r.BytesR.ReadByte() -} - -func (w *Writer) U8(v uint8) { - w.BytesW.WriteByte(v) -} - -func (r *Reader) readU64_bits(minSize int, bitsForSize int) uint64 { - size := r.BitsR.Read(bitsForSize) - size += uint(minSize) - return readUint64BitCompact(r.BytesR, int(size)) -} - -func (w *Writer) writeU64_bits(minSize int, bitsForSize int, v uint64) { - size := writeUint64BitCompact(w.BytesW, v, minSize) - w.BitsW.Write(bitsForSize, uint(size-minSize)) -} - -func (r *Reader) U16() uint16 { - v64 := r.readU64_bits(1, 1) - return uint16(v64) -} - -func (w *Writer) U16(v uint16) { - w.writeU64_bits(1, 1, uint64(v)) -} - -func (r *Reader) U32() uint32 { - v64 := r.readU64_bits(1, 2) - return uint32(v64) -} - -func (w *Writer) U32(v uint32) { - w.writeU64_bits(1, 2, uint64(v)) -} - -func (r *Reader) U64() uint64 { - return r.readU64_bits(1, 3) -} - -func (w *Writer) U64(v uint64) { - w.writeU64_bits(1, 3, v) -} - -func (r *Reader) VarUint() uint64 { - return r.readU64_bits(1, 3) -} - -func (w *Writer) VarUint(v uint64) { - w.writeU64_bits(1, 3, v) -} - -func (r *Reader) I64() int64 { - neg := r.Bool() - abs := r.U64() - if neg && abs == 0 { - panic(ErrNonCanonicalEncoding) - } - if neg { - return -int64(abs) - } - return int64(abs) -} - -func (w *Writer) I64(v int64) { - w.Bool(v < 0) - if v < 0 { - w.U64(uint64(-v)) - } else { - w.U64(uint64(v)) - } -} - -func (r *Reader) U56() uint64 { - return r.readU64_bits(0, 3) -} - -func (w *Writer) U56(v uint64) { - const max = 1<<(8*7) - 1 - if v > max { - panic("Value too big") - } - w.writeU64_bits(0, 3, v) -} - -func (r *Reader) Bool() bool { - u8 := r.BitsR.Read(1) - return u8 != 0 -} - -func (w *Writer) Bool(v bool) { - u8 := uint(0) - if v { - u8 = 1 - } - w.BitsW.Write(1, u8) -} - -func (r *Reader) FixedBytes(v []byte) { - buf := r.BytesR.Read(len(v)) - copy(v, buf) -} - -func (w *Writer) FixedBytes(v []byte) { - w.BytesW.Write(v) -} - -func (r *Reader) SliceBytes(maxLen int) []byte { - // read slice size - size := r.U56() - if size > uint64(maxLen) { - panic(ErrTooLargeAlloc) - } - buf := make([]byte, size) - // read slice content - r.FixedBytes(buf) - return buf -} - -func (w *Writer) SliceBytes(v []byte) { - // write slice size - w.U56(uint64(len(v))) - // write slice content - w.FixedBytes(v) -} - -// PaddedBytes returns a slice with length of the slice is at least n bytes. -func PaddedBytes(b []byte, n int) []byte { - if len(b) >= n { - return b - } - padding := make([]byte, n-len(b)) - return append(padding, b...) -} - -func (w *Writer) BigInt(v *big.Int) { - // serialize as an ordinary slice - bigBytes := []byte{} - if v.Sign() != 0 { - bigBytes = v.Bytes() - } - w.SliceBytes(bigBytes) -} - -func (r *Reader) BigInt() *big.Int { - // deserialize as an ordinary slice - buf := r.SliceBytes(512) - if len(buf) == 0 { - return new(big.Int) - } - return new(big.Int).SetBytes(buf) -} diff --git a/evm/go-x1/utils/cser/read_writer_test.go b/evm/go-x1/utils/cser/read_writer_test.go deleted file mode 100644 index 4b5fbc2..0000000 --- a/evm/go-x1/utils/cser/read_writer_test.go +++ /dev/null @@ -1,97 +0,0 @@ -package cser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/utils/bits" - "github.com/Fantom-foundation/go-opera/utils/fast" -) - -func TestUint64Compact(t *testing.T) { - require := require.New(t) - var ( - canonical = []byte{0b01111111, 0b11111111} - nonCanonical = []byte{0b01111111, 0b01111111, 0b10000000} - ) - - r := fast.NewReader(canonical) - got := readUint64Compact(r) - require.Equal(uint64(0x3fff), got) - - r = fast.NewReader(nonCanonical) - require.Panics(func() { - _ = readUint64Compact(r) - }) -} - -func TestUint64BitCompact(t *testing.T) { - require := require.New(t) - var ( - canonical = []byte{0b11111111, 0b00111111} - nonCanonical = []byte{0b01111111, 0b01111111, 0b00000000} - ) - - r := fast.NewReader(canonical) - got := readUint64BitCompact(r, len(canonical)) - require.Equal(uint64(0x3fff), got) - - r = fast.NewReader(nonCanonical) - require.Panics(func() { - _ = readUint64BitCompact(r, len(nonCanonical)) - }) -} - -func TestI64(t *testing.T) { - require := require.New(t) - - w := NewWriter() - - canonical := w.I64 - nonCanonical := func(v int64) { - w.Bool(v <= 0) - if v < 0 { - w.U64(uint64(-v)) - } else { - w.U64(uint64(v)) - } - } - - canonical(0) - nonCanonical(0) - - r := &Reader{ - BitsR: bits.NewReader(w.BitsW.Array), - BytesR: fast.NewReader(w.BytesW.Bytes()), - } - - got := r.I64() - require.Zero(got) - - require.Panics(func() { - _ = r.I64() - }) -} - -func TestPaddedBytes(t *testing.T) { - require := require.New(t) - - var data = []struct { - In []byte - N int - Exp []byte - }{ - {In: nil, N: 0, Exp: nil}, - {In: []byte{}, N: 0, Exp: []byte{}}, - {In: nil, N: 1, Exp: []byte{0}}, - {In: []byte{}, N: 1, Exp: []byte{0}}, - {In: []byte{10, 20}, N: 1, Exp: []byte{10, 20}}, - {In: []byte{10, 20}, N: 4, Exp: []byte{0, 0, 10, 20}}, - } - - for i, d := range data { - got := PaddedBytes(d.In, d.N) - require.Equal(d.Exp, got, i) - } -} diff --git a/evm/go-x1/utils/dbutil/asyncflushproducer/producer.go b/evm/go-x1/utils/dbutil/asyncflushproducer/producer.go deleted file mode 100644 index f16dc21..0000000 --- a/evm/go-x1/utils/dbutil/asyncflushproducer/producer.go +++ /dev/null @@ -1,78 +0,0 @@ -package asyncflushproducer - -import ( - "errors" - "sync" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/metrics" -) - -type Producer struct { - kvdb.FullDBProducer - mu sync.Mutex - dbs map[string]*store - stats metrics.Meter - - threshold uint64 -} - -func Wrap(backend kvdb.FullDBProducer, threshold uint64) *Producer { - return &Producer{ - stats: metrics.NewMeterForced(), - FullDBProducer: backend, - dbs: make(map[string]*store), - threshold: threshold, - } -} - -func (f *Producer) OpenDB(name string) (kvdb.Store, error) { - f.mu.Lock() - defer f.mu.Unlock() - // open existing DB - openedDB := f.dbs[name] - if openedDB != nil { - return openedDB, nil - } - // create new DB - db, err := f.FullDBProducer.OpenDB(name) - if err != nil { - return nil, err - } - if f.dbs[name] != nil { - return nil, errors.New("already opened") - } - wrapped := &store{ - Store: db, - CloseFn: func() error { - f.mu.Lock() - delete(f.dbs, name) - f.mu.Unlock() - return db.Close() - }, - } - f.dbs[name] = wrapped - return wrapped, nil -} - -func (f *Producer) Flush(id []byte) error { - f.stats.Mark(int64(f.FullDBProducer.NotFlushedSizeEst())) - - err := f.FullDBProducer.Flush(id) - if err != nil { - return err - } - - // trigger flushing data to disk if throughput is below a threshold - if uint64(f.stats.Rate1()) <= f.threshold { - go func() { - f.mu.Lock() - defer f.mu.Unlock() - for _, db := range f.dbs { - _, _ = db.Stat("async_flush") - } - }() - } - - return nil -} diff --git a/evm/go-x1/utils/dbutil/asyncflushproducer/store.go b/evm/go-x1/utils/dbutil/asyncflushproducer/store.go deleted file mode 100644 index 1aa57d8..0000000 --- a/evm/go-x1/utils/dbutil/asyncflushproducer/store.go +++ /dev/null @@ -1,14 +0,0 @@ -package asyncflushproducer - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb" -) - -type store struct { - kvdb.Store - CloseFn func() error -} - -func (s *store) Close() error { - return s.CloseFn() -} diff --git a/evm/go-x1/utils/dbutil/autocompact/store.go b/evm/go-x1/utils/dbutil/autocompact/store.go deleted file mode 100644 index 85e4f76..0000000 --- a/evm/go-x1/utils/dbutil/autocompact/store.go +++ /dev/null @@ -1,143 +0,0 @@ -package autocompact - -import ( - "sync" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/log" - "github.com/status-im/keycard-go/hexutils" -) - -// Store implements automatic compacting of recently inserted/erased data according to provided strategy -type Store struct { - kvdb.Store - limit uint64 - cont ContainerI - newCont func() ContainerI - compMu sync.Mutex - name string -} - -type Batch struct { - kvdb.Batch - store *Store - cont ContainerI -} - -func Wrap(s kvdb.Store, limit uint64, strategy func() ContainerI, name string) *Store { - return &Store{ - Store: s, - limit: limit, - newCont: strategy, - cont: strategy(), - name: name, - } -} - -func Wrap2(s kvdb.Store, limit1 uint64, limit2 uint64, strategy func() ContainerI, name string) *Store { - return Wrap(Wrap(s, limit1, strategy, name), limit2, strategy, name) -} - -func Wrap2M(s kvdb.Store, limit1 uint64, limit2 uint64, forward bool, name string) *Store { - strategy := NewBackwardsCont - if forward { - strategy = NewForwardCont - } - return Wrap2(s, limit1, limit2, strategy, name) -} - -func estSize(keyLen int, valLen int) uint64 { - // Storage overheads, related to adding/deleting a record, - //wouldn't be only proportional to length of key and value. - //E.g. if one adds 10 records with length of 2, it will be more expensive than 1 record with length 20 - // Now, 64 wasn't really calculated but is rather a guesstimation - return uint64(keyLen + valLen + 64) -} - -func (s *Store) onWrite(key []byte, size uint64) { - s.compMu.Lock() - defer s.compMu.Unlock() - if key != nil { - s.cont.Add(key, size) - } - s.mayCompact(false) -} - -func (s *Store) onBatchWrite(batchCont ContainerI) { - s.compMu.Lock() - defer s.compMu.Unlock() - s.cont.Merge(batchCont) - s.mayCompact(false) -} - -func (s *Store) compact() { - s.compMu.Lock() - defer s.compMu.Unlock() - s.mayCompact(true) -} - -func (s *Store) mayCompact(force bool) { - // error handling - err := s.cont.Error() - if err != nil { - s.cont.Reset() - s.newCont = NewDevnullCont - s.cont = s.newCont() - log.Warn("Autocompaction failed, which may lead to performance issues", "name", s.name, "err", err) - } - - if force || s.cont.Size() > s.limit { - for _, r := range s.cont.Ranges() { - log.Debug("Autocompact", "name", s.name, "from", hexutils.BytesToHex(r.minKey), "to", hexutils.BytesToHex(r.maxKey)) - _ = s.Store.Compact(r.minKey, r.maxKey) - } - s.cont.Reset() - } -} - -func (s *Store) Put(key []byte, value []byte) error { - defer s.onWrite(key, estSize(len(key), len(value))) - return s.Store.Put(key, value) -} - -func (s *Store) Delete(key []byte) error { - defer s.onWrite(key, estSize(len(key), 0)) - return s.Store.Delete(key) -} - -func (s *Store) Close() error { - s.compact() - return s.Store.Close() -} - -func (s *Store) NewBatch() kvdb.Batch { - batch := s.Store.NewBatch() - if batch == nil { - return nil - } - return &Batch{ - Batch: batch, - store: s, - cont: s.newCont(), - } -} - -func (s *Batch) Put(key []byte, value []byte) error { - s.cont.Add(key, estSize(len(key), len(value))) - return s.Batch.Put(key, value) -} - -func (s *Batch) Delete(key []byte) error { - s.cont.Add(key, estSize(len(key), 0)) - return s.Batch.Delete(key) -} - -func (s *Batch) Reset() { - s.cont.Reset() - s.Batch.Reset() -} - -func (s *Batch) Write() error { - defer s.store.onBatchWrite(s.cont) - return s.Batch.Write() -} diff --git a/evm/go-x1/utils/dbutil/autocompact/strategy.go b/evm/go-x1/utils/dbutil/autocompact/strategy.go deleted file mode 100644 index 1d6bc45..0000000 --- a/evm/go-x1/utils/dbutil/autocompact/strategy.go +++ /dev/null @@ -1,137 +0,0 @@ -package autocompact - -import ( - "bytes" - "errors" - - "github.com/ethereum/go-ethereum/common" -) - -type ContainerI interface { - Add(key []byte, size uint64) - Merge(c ContainerI) - Error() error - Reset() - Size() uint64 - Ranges() []Range -} - -type Range struct { - minKey []byte - maxKey []byte -} - -// MonotonicContainer implements tracking of compaction ranges in cases when keys are inserted as series of monotonic ranges -type MonotonicContainer struct { - forward bool - ranges []Range - size uint64 - err error -} - -type DevnullContainer struct{} - -func (d DevnullContainer) Add(key []byte, size uint64) {} - -func (d DevnullContainer) Merge(c ContainerI) {} - -func (d DevnullContainer) Error() error { - return nil -} - -func (d DevnullContainer) Reset() { - -} - -func (d DevnullContainer) Size() uint64 { - return 0 -} - -func (d DevnullContainer) Ranges() []Range { - return []Range{} -} - -func NewForwardCont() ContainerI { - return &MonotonicContainer{ - forward: true, - } -} - -func NewBackwardsCont() ContainerI { - return &MonotonicContainer{ - forward: false, - } -} - -func NewDevnullCont() ContainerI { - return DevnullContainer{} -} - -func (m *MonotonicContainer) addRange(key []byte) { - m.ranges = append(m.ranges, Range{ - minKey: common.CopyBytes(key), - maxKey: common.CopyBytes(key), - }) -} - -func (m *MonotonicContainer) Add(key []byte, size uint64) { - m.size += size - if len(m.ranges) == 0 { - m.addRange(key) - } - // extend the last range if it's a monotonic addition or start new range otherwise - l := len(m.ranges) - 1 - if m.forward { - if bytes.Compare(key, m.ranges[l].maxKey) >= 0 { - m.ranges[l].maxKey = common.CopyBytes(key) - } else { - m.addRange(key) - } - } else { - if bytes.Compare(key, m.ranges[l].minKey) <= 0 { - m.ranges[l].minKey = common.CopyBytes(key) - } else { - m.addRange(key) - } - } -} - -func (m *MonotonicContainer) Merge(c ContainerI) { - if err := c.Error(); err != nil { - m.err = err - } - - for _, r := range c.Ranges() { - if m.forward { - m.Add(r.minKey, 0) - m.Add(r.maxKey, 0) - } else { - m.Add(r.maxKey, 0) - m.Add(r.minKey, 0) - } - } - m.size += c.Size() -} - -func (m *MonotonicContainer) Error() error { - if m.err != nil { - return m.err - } - if len(m.ranges) > 2 { - return errors.New("too many compaction ranges, it's likely that dataset isn't monotonic enough") - } - return nil -} - -func (m *MonotonicContainer) Reset() { - m.ranges = nil - m.size = 0 -} - -func (m *MonotonicContainer) Size() uint64 { - return m.size -} - -func (m *MonotonicContainer) Ranges() []Range { - return m.ranges -} diff --git a/evm/go-x1/utils/dbutil/compactdb/compactdb.go b/evm/go-x1/utils/dbutil/compactdb/compactdb.go deleted file mode 100644 index b60ca39..0000000 --- a/evm/go-x1/utils/dbutil/compactdb/compactdb.go +++ /dev/null @@ -1,99 +0,0 @@ -package compactdb - -import ( - "errors" - "math/big" - "strconv" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" - - "github.com/Fantom-foundation/go-opera/utils" -) - -type contCompacter struct { - kvdb.Store - prev []byte -} - -func (s *contCompacter) Compact(_ []byte, limit []byte) error { - err := s.Store.Compact(s.prev, limit) - if err != nil { - return err - } - s.prev = limit - return nil -} - -func compact(db *contCompacter, prefix []byte, iters int) error { - // use heuristic to locate tables - nonEmptyPrefixes := make([]byte, 0, 256) - for b := 0; b < 256; b++ { - if !isEmptyDB(table.New(db, append(prefix, byte(b)))) { - nonEmptyPrefixes = append(nonEmptyPrefixes, byte(b)) - } - } - if len(nonEmptyPrefixes) == 0 { - return nil - } - if len(nonEmptyPrefixes) != 1 && len(nonEmptyPrefixes) < 50 { - // compact each table individually - for _, b := range nonEmptyPrefixes { - if err := compact(db, append(prefix, b), iters); err != nil { - return err - } - } - return nil - } - - // once a table is located, split the range into *iters* chunks for compaction - prefixed := utils.NewTableOrSelf(db, append(prefix)) - first, _, diff := keysRange(prefixed) - if diff.Cmp(big.NewInt(int64(iters+10000))) < 0 { - // skip if too few keys and compact it along with next range - return nil - } - firstBn := new(big.Int).SetBytes(first) - for i := iters; i >= 1; i-- { - until := addToKey(firstBn, new(big.Int).Div(diff, big.NewInt(int64(i))), len(first)) - if err := prefixed.Compact(nil, until); err != nil { - return err - } - } - return nil -} - -func Compact(db kvdb.Store, loggingName string, sizePerIter uint64) error { - loggedDB := &loggedCompacter{ - Store: db, - name: loggingName, - quit: make(chan struct{}), - } - loggedDB.StartLogging() - defer loggedDB.StopLogging() - - // scale number of iterations based on total DB size and sizePerIter - diskSizeStr, err := db.Stat("disk.size") - if err != nil { - return err - } - var nDiskSize int64 - if nDiskSize, err = strconv.ParseInt(diskSizeStr, 10, 64); err != nil || nDiskSize < 0 { - return errors.New("bad syntax of disk size entry") - } - - iters := uint64(nDiskSize) / sizePerIter - if iters <= 1 { - // short circuit if too few iterations - return loggedDB.Compact(nil, nil) - } - - compacter := &contCompacter{ - Store: loggedDB, - } - err = compact(compacter, []byte{}, int(iters)) - if err != nil { - return err - } - return compacter.Compact(nil, nil) -} diff --git a/evm/go-x1/utils/dbutil/compactdb/keys.go b/evm/go-x1/utils/dbutil/compactdb/keys.go deleted file mode 100644 index 93c6910..0000000 --- a/evm/go-x1/utils/dbutil/compactdb/keys.go +++ /dev/null @@ -1,96 +0,0 @@ -package compactdb - -import ( - "bytes" - "math/big" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" - "github.com/ethereum/go-ethereum/common" -) - -func isEmptyDB(db kvdb.Iteratee) bool { - it := db.NewIterator(nil, nil) - defer it.Release() - return !it.Next() -} - -func firstKey(db kvdb.Store) []byte { - it := db.NewIterator(nil, nil) - defer it.Release() - if !it.Next() { - return nil - } - return common.CopyBytes(it.Key()) -} - -func lastKey(db kvdb.Store) []byte { - var start []byte - for { - for b := 0xff; b >= 0; b-- { - if !isEmptyDB(table.New(db, append(start, byte(b)))) { - start = append(start, byte(b)) - break - } - if b == 0 { - return start - } - } - } -} - -func keysRange(db kvdb.Store) ([]byte, []byte, *big.Int) { - first := firstKey(db) - if first == nil { - return nil, nil, big.NewInt(0) - } - last := lastKey(db) - if last == nil { - return nil, nil, big.NewInt(0) - } - keySize := len(last) - if keySize < len(first) { - keySize = len(first) - } - first = common.RightPadBytes(first, keySize) - last = common.RightPadBytes(last, keySize) - firstBn := new(big.Int).SetBytes(first) - lastBn := new(big.Int).SetBytes(last) - return first, last, new(big.Int).Sub(lastBn, firstBn) -} - -func addToKey(prefix *big.Int, diff *big.Int, size int) []byte { - endBn := new(big.Int).Set(prefix) - endBn.Add(endBn, diff) - if len(endBn.Bytes()) > size { - // overflow - return bytes.Repeat([]byte{0xff}, size) - } - end := endBn.Bytes() - res := make([]byte, size-len(end), size) - return append(res, end...) -} - -// trimAfterDiff erases all bytes after first *maxDiff* differences between *a* and *b* -func trimAfterDiff(a, b []byte, maxDiff int) ([]byte, []byte) { - size := len(a) - if size > len(b) { - size = len(b) - } - for i := 0; i < size; i++ { - if a[i] != b[i] { - maxDiff-- - if maxDiff <= 0 { - size = i + 1 - break - } - } - } - if len(a) > size { - a = a[:size] - } - if len(b) > size { - b = b[:size] - } - return a, b -} diff --git a/evm/go-x1/utils/dbutil/compactdb/keys_test.go b/evm/go-x1/utils/dbutil/compactdb/keys_test.go deleted file mode 100644 index 6d1ac6f..0000000 --- a/evm/go-x1/utils/dbutil/compactdb/keys_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package compactdb - -import ( - "io/ioutil" - "path" - "testing" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/leveldb" - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" - "github.com/Fantom-foundation/lachesis-base/kvdb/pebble" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb/opt" -) - -func tmpDir(name string) string { - dir, err := ioutil.TempDir("", name) - if err != nil { - panic(err) - } - return dir -} - -func TestLastKey(t *testing.T) { - testLastKey(t, memorydb.New()) - dir := tmpDir("test-last-key") - ldb, err := leveldb.New(path.Join(dir, "ldb"), 16*opt.MiB, 64, nil, nil) - require.NoError(t, err) - defer ldb.Close() - testLastKey(t, ldb) - pbl, err := pebble.New(path.Join(dir, "pbl"), 16*opt.MiB, 64, nil, nil) - require.NoError(t, err) - defer pbl.Close() - testLastKey(t, pbl) -} - -func testLastKey(t *testing.T, db kvdb.Store) { - require.Nil(t, lastKey(db)) - - db.Put([]byte{0}, []byte{0}) - require.Equal(t, []byte{0}, lastKey(db)) - - db.Put([]byte{1}, []byte{0}) - require.Equal(t, []byte{1}, lastKey(db)) - - db.Put([]byte{2}, []byte{0}) - require.Equal(t, []byte{2}, lastKey(db)) - - db.Put([]byte{1, 0}, []byte{0}) - require.Equal(t, []byte{2}, lastKey(db)) - - db.Put([]byte{3}, []byte{0}) - require.Equal(t, []byte{3}, lastKey(db)) - - db.Put([]byte{3, 0}, []byte{0}) - require.Equal(t, []byte{3, 0}, lastKey(db)) - - db.Put([]byte{3, 1}, []byte{0}) - require.Equal(t, []byte{3, 1}, lastKey(db)) - - db.Put([]byte{4}, []byte{0}) - require.Equal(t, []byte{4}, lastKey(db)) - - db.Put([]byte{4, 0, 0, 0}, []byte{0}) - require.Equal(t, []byte{4, 0, 0, 0}, lastKey(db)) - - db.Put([]byte{4, 0, 1, 0}, []byte{0}) - require.Equal(t, []byte{4, 0, 1, 0}, lastKey(db)) -} - -func TestTrimAfterDiff(t *testing.T) { - a, b := trimAfterDiff([]byte{}, []byte{}, 1) - require.Equal(t, []byte{}, a) - require.Equal(t, []byte{}, b) - - - a, b = trimAfterDiff([]byte{1, 2}, []byte{1, 3}, 1) - require.Equal(t, []byte{1, 2}, a) - require.Equal(t, []byte{1, 3}, b) - - a, b = trimAfterDiff([]byte{1, 2, 4}, []byte{1, 3, 4}, 1) - require.Equal(t, []byte{1, 2}, a) - require.Equal(t, []byte{1, 3}, b) - - a, b = trimAfterDiff([]byte{1, 2, 4, 5}, []byte{1, 3, 4, 6}, 1) - require.Equal(t, []byte{1, 2}, a) - require.Equal(t, []byte{1, 3}, b) - - a, b = trimAfterDiff([]byte{1, 2, 4, 5}, []byte{1, 3, 4, 6}, 2) - require.Equal(t, []byte{1, 2, 4, 5}, a) - require.Equal(t, []byte{1, 3, 4, 6}, b) - - a, b = trimAfterDiff([]byte{1, 2, 4, 5, 7}, []byte{1, 3, 4, 6}, 2) - require.Equal(t, []byte{1, 2, 4, 5}, a) - require.Equal(t, []byte{1, 3, 4, 6}, b) - - a, b = trimAfterDiff([]byte{1, 2, 4, 5, 7}, []byte{1, 3, 4, 6, 7}, 2) - require.Equal(t, []byte{1, 2, 4, 5}, a) - require.Equal(t, []byte{1, 3, 4, 6}, b) - - a, b = trimAfterDiff([]byte{1, 2, 4, 5, 7}, []byte{1, 3, 4}, 2) - require.Equal(t, []byte{1, 2, 4}, a) - require.Equal(t, []byte{1, 3, 4}, b) -} diff --git a/evm/go-x1/utils/dbutil/compactdb/log.go b/evm/go-x1/utils/dbutil/compactdb/log.go deleted file mode 100644 index 6156434..0000000 --- a/evm/go-x1/utils/dbutil/compactdb/log.go +++ /dev/null @@ -1,65 +0,0 @@ -package compactdb - -import ( - "sync" - "sync/atomic" - "time" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/log" - "github.com/status-im/keycard-go/hexutils" -) - -type loggedCompacter struct { - kvdb.Store - name string - - currentOp atomic.Value - - wg sync.WaitGroup - quit chan struct{} -} - -type pair struct { - p, l []byte -} - -func (s *loggedCompacter) Compact(prev []byte, limit []byte) error { - s.currentOp.Store(pair{prev, limit}) - if err := s.Store.Compact(prev, limit); err != nil { - log.Error("Compaction error", "name", s.name, "err", err) - return err - } - return nil -} - -func (s *loggedCompacter) StartLogging() { - s.wg.Add(1) - go func() { - defer s.wg.Done() - ticker := time.NewTicker(time.Minute) - for { - select { - case <-ticker.C: - opI := s.currentOp.Load() - if opI != nil { - op := opI.(pair) - // trim keys for nicer human-readable logging - op.p, op.l = trimAfterDiff(op.p, op.l, 2) - untilStr := hexutils.BytesToHex(op.l) - if len(op.l) == 0 { - untilStr = "end" - } - log.Info("Compacting DB", "name", s.name, "until", untilStr) - } - case <-s.quit: - return - } - } - }() -} - -func (s *loggedCompacter) StopLogging() { - close(s.quit) - s.wg.Wait() -} diff --git a/evm/go-x1/utils/dbutil/dbcounter/dbcounter.go b/evm/go-x1/utils/dbutil/dbcounter/dbcounter.go deleted file mode 100644 index 65ec85c..0000000 --- a/evm/go-x1/utils/dbutil/dbcounter/dbcounter.go +++ /dev/null @@ -1,99 +0,0 @@ -package dbcounter - -import ( - "fmt" - "sync/atomic" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/log" -) - -type DBProducer struct { - kvdb.IterableDBProducer - warn bool -} - -type Iterator struct { - kvdb.Iterator - itCounter *int64 - start []byte - prefix []byte -} - -type Snapshot struct { - kvdb.Snapshot - snCounter *int64 -} - -type Store struct { - kvdb.Store - name string - snCounter int64 - itCounter int64 - warn bool -} - -func Wrap(db kvdb.IterableDBProducer, warn bool) kvdb.IterableDBProducer { - return &DBProducer{db, warn} -} - -func WrapStore(s kvdb.Store, name string, warn bool) *Store { - return &Store{ - Store: s, - name: name, - warn: warn, - } -} - -func (ds *Store) Close() error { - itCounter, snCounter := atomic.LoadInt64(&ds.itCounter), atomic.LoadInt64(&ds.snCounter) - if itCounter != 0 || snCounter != 0 { - err := fmt.Errorf("%s DB leak: %d iterators, %d snapshots", ds.name, itCounter, snCounter) - if ds.warn { - log.Warn("Possible " + err.Error()) - } else { - return err - } - } - return ds.Store.Close() -} - -func (ds *Snapshot) Release() { - atomic.AddInt64(ds.snCounter, -1) - ds.Snapshot.Release() -} - -func (ds *Store) NewIterator(prefix []byte, start []byte) kvdb.Iterator { - atomic.AddInt64(&ds.itCounter, 1) - return &Iterator{ - Iterator: ds.Store.NewIterator(prefix, start), - itCounter: &ds.itCounter, - start: start, - prefix: prefix, - } -} - -func (it *Iterator) Release() { - atomic.AddInt64(it.itCounter, -1) - it.Iterator.Release() -} - -func (ds *Store) GetSnapshot() (kvdb.Snapshot, error) { - atomic.AddInt64(&ds.snCounter, 1) - snapshot, err := ds.Store.GetSnapshot() - if err != nil { - return nil, err - } - return &Snapshot{ - Snapshot: snapshot, - snCounter: &ds.snCounter, - }, nil -} - -func (db *DBProducer) OpenDB(name string) (kvdb.Store, error) { - s, err := db.IterableDBProducer.OpenDB(name) - if err != nil { - return nil, err - } - return WrapStore(s, name, db.warn), nil -} diff --git a/evm/go-x1/utils/dbutil/itergc/iterator_gc.go b/evm/go-x1/utils/dbutil/itergc/iterator_gc.go deleted file mode 100644 index 74ccdfd..0000000 --- a/evm/go-x1/utils/dbutil/itergc/iterator_gc.go +++ /dev/null @@ -1,64 +0,0 @@ -package itergc - -import ( - "sync" - - "github.com/Fantom-foundation/lachesis-base/kvdb" -) - -type Snapshot struct { - kvdb.Snapshot - nextID uint64 - iters map[uint64]kvdb.Iterator - mu sync.Locker -} - -type Iterator struct { - kvdb.Iterator - mu sync.Locker - id uint64 - iters map[uint64]kvdb.Iterator -} - -// Wrap snapshot to automatically close all pending iterators upon snapshot release -func Wrap(snapshot kvdb.Snapshot, mu sync.Locker) *Snapshot { - return &Snapshot{ - Snapshot: snapshot, - iters: make(map[uint64]kvdb.Iterator), - mu: mu, - } -} - -func (s *Snapshot) NewIterator(prefix []byte, start []byte) kvdb.Iterator { - s.mu.Lock() - defer s.mu.Unlock() - it := s.Snapshot.NewIterator(prefix, start) - id := s.nextID - s.iters[id] = it - s.nextID++ - - return &Iterator{ - Iterator: it, - mu: s.mu, - id: id, - iters: s.iters, - } -} - -func (s *Iterator) Release() { - s.mu.Lock() - defer s.mu.Unlock() - s.Iterator.Release() - delete(s.iters, s.id) -} - -func (s *Snapshot) Release() { - s.mu.Lock() - defer s.mu.Unlock() - // release all pending iterators - for _, it := range s.iters { - it.Release() - } - s.iters = nil - s.Snapshot.Release() -} diff --git a/evm/go-x1/utils/dbutil/switchable/snapshot.go b/evm/go-x1/utils/dbutil/switchable/snapshot.go deleted file mode 100644 index 1cc16b1..0000000 --- a/evm/go-x1/utils/dbutil/switchable/snapshot.go +++ /dev/null @@ -1,152 +0,0 @@ -package switchable - -import ( - "sync" - - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/common" - - "github.com/Fantom-foundation/go-opera/utils/dbutil/itergc" -) - -type Snapshot struct { - kvdb.Snapshot - mu sync.RWMutex -} - -func (s *Snapshot) SwitchTo(snap kvdb.Snapshot) kvdb.Snapshot { - s.mu.Lock() - defer s.mu.Unlock() - old := s.Snapshot - s.Snapshot = itergc.Wrap(snap, &sync.Mutex{}) - return old -} - -func Wrap(snap kvdb.Snapshot) *Snapshot { - s := &Snapshot{} - s.SwitchTo(snap) - return s -} - -// Has checks if key is in the exists. -func (s *Snapshot) Has(key []byte) (bool, error) { - s.mu.RLock() - defer s.mu.RUnlock() - - return s.Snapshot.Has(key) -} - -// Get returns key-value pair by key. -func (s *Snapshot) Get(key []byte) ([]byte, error) { - s.mu.RLock() - defer s.mu.RUnlock() - - return s.Snapshot.Get(key) -} - -func (s *Snapshot) Release() { - s.mu.Lock() - defer s.mu.Unlock() - - s.Snapshot.Release() -} - -// NewIterator creates a binary-alphabetical iterator over a subset -// of database content with a particular key prefix, starting at a particular -// initial key (or after, if it does not exist). -func (s *Snapshot) NewIterator(prefix []byte, start []byte) kvdb.Iterator { - s.mu.RLock() - defer s.mu.RUnlock() - - return &switchableIterator{ - mu: &s.mu, - upd: &s.Snapshot, - cur: s.Snapshot, - parentIt: s.Snapshot.NewIterator(prefix, start), - prefix: prefix, - start: start, - } -} - -/* - * Iterator - */ - -type switchableIterator struct { - mu *sync.RWMutex - upd *kvdb.Snapshot - cur kvdb.Snapshot - parentIt kvdb.Iterator - - prefix, start []byte - key, value []byte -} - -func (it *switchableIterator) mayReopen() { - if it.cur != *it.upd { - // reopen iterator if DB was switched - it.cur = *it.upd - if it.key != nil { - it.start = common.CopyBytes(it.key[len(it.prefix):]) - } - it.parentIt = it.cur.NewIterator(it.prefix, it.start) - if it.key != nil { - _ = it.parentIt.Next() // skip previous key - } - } -} - -// Next scans key-value pair by key in lexicographic order. Looks in cache first, -// then - in DB. -func (it *switchableIterator) Next() bool { - it.mu.Lock() - defer it.mu.Unlock() - - it.mayReopen() - - ok := it.parentIt.Next() - if !ok { - it.key = nil - it.value = nil - return false - } - it.key = it.parentIt.Key() - it.value = it.parentIt.Value() - return true -} - -// Error returns any accumulated error. Exhausting all the key/value pairs -// is not considered to be an error. A memory iterator cannot encounter errors. -func (it *switchableIterator) Error() error { - it.mu.Lock() - defer it.mu.Unlock() - - it.mayReopen() - - return it.parentIt.Error() -} - -// Key returns the key of the current key/value pair, or nil if done. The caller -// should not modify the contents of the returned slice, and its contents may -// change on the next call to Next. -func (it *switchableIterator) Key() []byte { - return it.key -} - -// Value returns the value of the current key/value pair, or nil if done. The -// caller should not modify the contents of the returned slice, and its contents -// may change on the next call to Next. -func (it *switchableIterator) Value() []byte { - return it.value -} - -// Release releases associated resources. Release should always succeed and can -// be called multiple times without causing error. -func (it *switchableIterator) Release() { - it.mu.Lock() - defer it.mu.Unlock() - - it.mayReopen() - - it.parentIt.Release() -} diff --git a/evm/go-x1/utils/dbutil/switchable/snapshot_test.go b/evm/go-x1/utils/dbutil/switchable/snapshot_test.go deleted file mode 100644 index 88e51e6..0000000 --- a/evm/go-x1/utils/dbutil/switchable/snapshot_test.go +++ /dev/null @@ -1,152 +0,0 @@ -package switchable - -import ( - "math/rand" - "sync" - "sync/atomic" - "testing" - "time" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/utils/dbutil/dbcounter" -) - -func decodePair(b []byte) (uint32, uint32) { - v1 := bigendian.BytesToUint32(b[:4]) - v2 := bigendian.BytesToUint32(b[4:]) - return v1, v2 -} - -type UncallableAfterRelease struct { - kvdb.Snapshot - iterators []*uncallableAfterReleaseIterator - mu sync.Mutex -} - -type uncallableAfterReleaseIterator struct { - kvdb.Iterator -} - -func (db *UncallableAfterRelease) NewIterator(prefix []byte, start []byte) kvdb.Iterator { - it := db.Snapshot.NewIterator(prefix, start) - wrapped := &uncallableAfterReleaseIterator{it} - - db.mu.Lock() - defer db.mu.Unlock() - db.iterators = append(db.iterators, wrapped) - - return wrapped -} - -func (db *UncallableAfterRelease) Release() { - db.Snapshot.Release() - // ensure nil pointer exception on any next call - db.Snapshot = nil - - db.mu.Lock() - defer db.mu.Unlock() - for _, it := range db.iterators { - it.Iterator = nil - } -} - -func TestSnapshot_SwitchTo(t *testing.T) { - require := require.New(t) - - const prefixes = 100 - const keys = 100 - const checkers = 5 - const switchers = 5 - const duration = time.Millisecond * 400 - - // fill DB with data - memdb := dbcounter.WrapStore(memorydb.New(), "", false) - for i := uint32(0); i < prefixes; i++ { - for j := uint32(0); j < keys; j++ { - key := append(bigendian.Uint32ToBytes(i), bigendian.Uint32ToBytes(j)...) - val := append(bigendian.Uint32ToBytes(i*i), bigendian.Uint32ToBytes(j*j)...) - require.NoError(memdb.Put(key, val)) - } - } - - // 4 readers, one interrupter - snap, err := memdb.GetSnapshot() - require.NoError(err) - switchable := Wrap(&UncallableAfterRelease{ - Snapshot: snap, - }) - - stop := uint32(0) - wg := sync.WaitGroup{} - wg.Add(checkers + switchers) - for worker := 0; worker < checkers; worker++ { - go func() { - defer wg.Done() - for atomic.LoadUint32(&stop) == 0 { - var prevPrefix uint32 - var prevKey uint32 - prefixN := rand.Uint32() % prefixes - prefix := bigendian.Uint32ToBytes(prefixN) - keyN := rand.Uint32() % prefixes - start := bigendian.Uint32ToBytes(keyN) - prevKey = keyN - 1 - if rand.Intn(10) == 0 { - start = nil - prevKey = 0 - prevKey-- - if rand.Intn(2) == 0 { - prefix = nil - prevPrefix = 0 - } - } - it := switchable.NewIterator(prefix, start) - require.NoError(it.Error()) - for it.Next() { - require.NoError(it.Error()) - require.Equal(8, len(it.Key())) - require.Equal(8, len(it.Value())) - p, k := decodePair(it.Key()) - sp, sk := decodePair(it.Value()) - require.Equal(p*p, sp) - require.Equal(k*k, sk) - if prefix != nil { - require.Equal(prefixN, p) - } else if p != prevPrefix { - require.Equal(prevPrefix+1, p) - prevPrefix = p - prevKey = 0 - prevKey-- - } - - require.Equal(prevKey+1, k, prefix) - prevKey = k - } - require.NoError(it.Error()) - it.Release() - } - }() - } - for worker := 0; worker < switchers; worker++ { - go func() { - defer wg.Done() - - for atomic.LoadUint32(&stop) == 0 { - snap, err := memdb.GetSnapshot() - require.NoError(err) - old := switchable.SwitchTo(&UncallableAfterRelease{ - Snapshot: snap, - }) - old.Release() - } - }() - } - time.Sleep(duration) - atomic.StoreUint32(&stop, 1) - wg.Wait() - switchable.Release() - require.NoError(memdb.Close()) -} diff --git a/evm/go-x1/utils/dbutil/threads/counted.go b/evm/go-x1/utils/dbutil/threads/counted.go deleted file mode 100644 index a91a865..0000000 --- a/evm/go-x1/utils/dbutil/threads/counted.go +++ /dev/null @@ -1,63 +0,0 @@ -package threads - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb" - - "github.com/Fantom-foundation/go-opera/logger" -) - -type ( - countedDbProducer struct { - kvdb.DBProducer - } - - countedFullDbProducer struct { - kvdb.FullDBProducer - } - - countedStore struct { - kvdb.Store - } - - countedIterator struct { - kvdb.Iterator - release func(count int) - } -) - -func CountedDBProducer(dbs kvdb.DBProducer) kvdb.DBProducer { - return &countedDbProducer{dbs} -} - -func CountedFullDBProducer(dbs kvdb.FullDBProducer) kvdb.FullDBProducer { - return &countedFullDbProducer{dbs} -} - -func (p *countedDbProducer) OpenDB(name string) (kvdb.Store, error) { - s, err := p.DBProducer.OpenDB(name) - return &countedStore{s}, err -} - -func (p *countedFullDbProducer) OpenDB(name string) (kvdb.Store, error) { - s, err := p.FullDBProducer.OpenDB(name) - return &countedStore{s}, err -} - -var notifier = logger.New("threads-pool") - -func (s *countedStore) NewIterator(prefix []byte, start []byte) kvdb.Iterator { - got, release := GlobalPool.Lock(1) - if got < 1 { - notifier.Log.Warn("Too many DB iterators") - } - - return &countedIterator{ - Iterator: s.Store.NewIterator(prefix, start), - release: release, - } -} - -func (it *countedIterator) Release() { - it.Iterator.Release() - it.release(1) -} diff --git a/evm/go-x1/utils/dbutil/threads/pool.go b/evm/go-x1/utils/dbutil/threads/pool.go deleted file mode 100644 index e151177..0000000 --- a/evm/go-x1/utils/dbutil/threads/pool.go +++ /dev/null @@ -1,77 +0,0 @@ -package threads - -import ( - "runtime/debug" - "sync" -) - -const GoroutinesPerThread = 0.8 - -// threadPool counts threads in use -type ThreadPool struct { - mu sync.Mutex - cap int - left int -} - -var GlobalPool ThreadPool - -// init ThreadPool only on demand to give time to other packages -// call debug.SetMaxThreads() if they need -func (p *ThreadPool) init() { - if p.cap == 0 { - p.cap = int(getMaxThreads() * GoroutinesPerThread) - p.left = p.cap - } -} - -// Capacity of pool -func (p *ThreadPool) Cap() int { - if p.cap == 0 { - p.mu.Lock() - defer p.mu.Unlock() - p.init() - } - return p.cap -} - -func (p *ThreadPool) Lock(want int) (got int, release func(count int)) { - p.mu.Lock() - defer p.mu.Unlock() - - p.init() - - if want < 1 { - want = 0 - } - - got = min(p.left, want) - p.left -= got - - release = func(count int) { - p.mu.Lock() - defer p.mu.Unlock() - - if 0 > count || count > got { - count = got - } - - got -= count - p.left += count - } - - return -} - -func getMaxThreads() float64 { - was := debug.SetMaxThreads(10000) - debug.SetMaxThreads(was) - return float64(was) -} - -func min(a, b int) int { - if a < b { - return a - } - return b -} diff --git a/evm/go-x1/utils/dbutil/threads/pool_test.go b/evm/go-x1/utils/dbutil/threads/pool_test.go deleted file mode 100644 index a2c31a9..0000000 --- a/evm/go-x1/utils/dbutil/threads/pool_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package threads - -import ( - "os" - "runtime/debug" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestMain(m *testing.M) { - debug.SetMaxThreads(10) - - os.Exit(m.Run()) -} - -func TestThreadPool(t *testing.T) { - - for name, pool := range map[string]ThreadPool{ - "global": GlobalPool, - "local": ThreadPool{}, - } { - t.Run(name, func(t *testing.T) { - require := require.New(t) - - require.Equal(8, pool.Cap()) - - got, release := pool.Lock(0) - require.Equal(0, got) - release(1) - - gotA, releaseA := pool.Lock(10) - require.Equal(8, gotA) - releaseA(1) - - gotB, releaseB := pool.Lock(10) - require.Equal(1, gotB) - releaseB(gotB) - - releaseA(gotA) - gotB, releaseB = pool.Lock(10) - require.Equal(8, gotB) - - // don't releaseB(gotB) to check pools isolation - }) - } -} diff --git a/evm/go-x1/utils/devnullfile/devnull.go b/evm/go-x1/utils/devnullfile/devnull.go deleted file mode 100644 index 8c394c3..0000000 --- a/evm/go-x1/utils/devnullfile/devnull.go +++ /dev/null @@ -1,26 +0,0 @@ -package devnullfile - -type DevNull struct{} - -func (d DevNull) Read(pp []byte) (n int, err error) { - for i := range pp { - pp[i] = 0 - } - return len(pp), nil -} - -func (d DevNull) Write(pp []byte) (n int, err error) { - return len(pp), nil -} - -func (d DevNull) Close() error { - return nil -} - -func (d DevNull) Seek(offset int64, whence int) (int64, error) { - return 0, nil -} - -func (d DevNull) Drop() error { - return nil -} diff --git a/evm/go-x1/utils/errlock/errlock.go b/evm/go-x1/utils/errlock/errlock.go deleted file mode 100644 index df0005a..0000000 --- a/evm/go-x1/utils/errlock/errlock.go +++ /dev/null @@ -1,74 +0,0 @@ -package errlock - -import ( - "io" - "io/ioutil" - "os" - "path" - - "github.com/ethereum/go-ethereum/cmd/utils" -) - -// Check if errlock is written -func Check() { - locked, reason, eLockPath, _ := read(datadir) - if locked { - utils.Fatalf("Node isn't allowed to start due to a previous error. Please fix the issue and then delete file \"%s\". Error message:\n%s", eLockPath, reason) - } -} - -var ( - datadir string -) - -// SetDefaultDatadir for errlock files -func SetDefaultDatadir(dir string) { - datadir = dir -} - -// Permanent error -func Permanent(err error) { - eLockPath, _ := write(datadir, err.Error()) - utils.Fatalf("Node is permanently stopping due to an issue. Please fix the issue and then delete file \"%s\". Error message:\n%s", eLockPath, err.Error()) -} - -func readAll(reader io.Reader, max int) ([]byte, error) { - buf := make([]byte, max) - consumed := 0 - for { - n, err := reader.Read(buf[consumed:]) - consumed += n - if consumed == len(buf) || err == io.EOF { - return buf[:consumed], nil - } - if err != nil { - return nil, err - } - } -} - -// read errlock file -func read(dir string) (bool, string, string, error) { - eLockPath := path.Join(dir, "errlock") - - data, err := os.Open(eLockPath) - if err != nil { - return false, "", eLockPath, err - } - defer data.Close() - - // read no more than N bytes - maxFileLen := 5000 - eLockBytes, err := readAll(data, maxFileLen) - if err != nil { - return true, "", eLockPath, err - } - return true, string(eLockBytes), eLockPath, nil -} - -// write errlock file -func write(dir string, eLockStr string) (string, error) { - eLockPath := path.Join(dir, "errlock") - - return eLockPath, ioutil.WriteFile(eLockPath, []byte(eLockStr), 0666) // assume no custom encoding needed -} diff --git a/evm/go-x1/utils/eventid/eventid.go b/evm/go-x1/utils/eventid/eventid.go deleted file mode 100644 index 82424dc..0000000 --- a/evm/go-x1/utils/eventid/eventid.go +++ /dev/null @@ -1,69 +0,0 @@ -package eventid - -import ( - "sync" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -type Cache struct { - ids map[hash.Event]bool - mu sync.RWMutex - maxSize int - epoch idx.Epoch -} - -func NewCache(maxSize int) *Cache { - return &Cache{ - maxSize: maxSize, - } -} - -func (c *Cache) Reset(epoch idx.Epoch) { - c.mu.Lock() - defer c.mu.Unlock() - c.ids = make(map[hash.Event]bool) - c.epoch = epoch -} - -func (c *Cache) Has(id hash.Event) (has bool, ok bool) { - c.mu.RLock() - defer c.mu.RUnlock() - - if c.ids == nil { - return false, false - } - if c.epoch != id.Epoch() { - return false, false - } - return c.ids[id], true -} - -func (c *Cache) Add(id hash.Event) bool { - c.mu.Lock() - defer c.mu.Unlock() - - if c.ids == nil { - return false - } - if c.epoch != id.Epoch() { - return false - } - if len(c.ids) >= c.maxSize { - c.ids = nil - return false - } - c.ids[id] = true - return true -} - -func (c *Cache) Remove(id hash.Event) { - c.mu.Lock() - defer c.mu.Unlock() - - if c.ids == nil { - return - } - delete(c.ids, id) -} diff --git a/evm/go-x1/utils/fast/buffer.go b/evm/go-x1/utils/fast/buffer.go deleted file mode 100644 index 06012eb..0000000 --- a/evm/go-x1/utils/fast/buffer.go +++ /dev/null @@ -1,73 +0,0 @@ -package fast - -type Reader struct { - buf []byte - offset int -} - -type Writer struct { - buf []byte -} - -// NewReader wraps bytes with reading buffer. -func NewReader(bb []byte) *Reader { - return &Reader{ - buf: bb, - offset: 0, - } -} - -// NewWriter wraps bytes with writing buffer. -func NewWriter(bb []byte) *Writer { - return &Writer{ - buf: bb, - } -} - -// WriteByte to the buffer. -func (b *Writer) WriteByte(v byte) { - b.buf = append(b.buf, v) -} - -// Write the byte to the buffer. -func (b *Writer) Write(v []byte) { - b.buf = append(b.buf, v...) -} - -// Read n bytes. -func (b *Reader) Read(n int) []byte { - var res []byte - res = b.buf[b.offset : b.offset+n] - b.offset += n - - return res -} - -// ReadByte reads 1 byte. -func (b *Reader) ReadByte() byte { - var res byte - res = b.buf[b.offset] - b.offset++ - - return res -} - -// Position of internal cursor. -func (b *Reader) Position() int { - return b.offset -} - -// Bytes of internal buffer -func (b *Reader) Bytes() []byte { - return b.buf -} - -// Bytes of internal buffer -func (b *Writer) Bytes() []byte { - return b.buf -} - -// Empty returns true if the whole buffer is consumed -func (b *Reader) Empty() bool { - return len(b.buf) == b.offset -} diff --git a/evm/go-x1/utils/fast/buffer_test.go b/evm/go-x1/utils/fast/buffer_test.go deleted file mode 100644 index fe9551d..0000000 --- a/evm/go-x1/utils/fast/buffer_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package fast - -import ( - "bytes" - "math/rand" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestBuffer(t *testing.T) { - const N = 100 - - var ( - w *Writer - r *Reader - bb = []byte{0, 0, 0xFF, 9, 0} - ) - - t.Run("Writer", func(t *testing.T) { - require := require.New(t) - - w = NewWriter(make([]byte, 0, N/2)) - for i := byte(0); i < N; i++ { - w.WriteByte(i) - } - require.Equal(N, len(w.Bytes())) - w.Write(bb) - require.Equal(N+len(bb), len(w.Bytes())) - }) - - t.Run("Reader", func(t *testing.T) { - require := require.New(t) - - r = NewReader(w.Bytes()) - require.Equal(N+len(bb), len(r.Bytes())) - require.False(r.Empty()) - for exp := byte(0); exp < N; exp++ { - got := r.ReadByte() - require.Equal(exp, got) - } - require.Equal(N, r.Position()) - got := r.Read(len(bb)) - require.Equal(bb, got) - require.True(r.Empty()) - }) -} - -func Benchmark(b *testing.B) { - b.Run("Write", func(b *testing.B) { - b.Run("Std", func(b *testing.B) { - w := bytes.NewBuffer(make([]byte, 0, b.N)) - for i := 0; i < b.N; i++ { - w.WriteByte(byte(i)) - } - require.Equal(b, b.N, len(w.Bytes())) - }) - b.Run("Fast", func(b *testing.B) { - w := NewWriter(make([]byte, 0, b.N)) - for i := 0; i < b.N; i++ { - w.WriteByte(byte(i)) - } - require.Equal(b, b.N, len(w.Bytes())) - }) - }) - - b.Run("Read", func(b *testing.B) { - src := make([]byte, 1000) - rand.Read(src) - - b.Run("Std", func(b *testing.B) { - for i := 0; i < b.N; i++ { - r := bytes.NewReader(src) - for j := 0; j < len(src); j++ { - _, _ = r.ReadByte() - } - } - }) - b.Run("Fast", func(b *testing.B) { - for i := 0; i < b.N; i++ { - r := NewReader(src) - for j := 0; j < len(src); j++ { - _ = r.ReadByte() - } - } - }) - }) -} diff --git a/evm/go-x1/utils/file.go b/evm/go-x1/utils/file.go deleted file mode 100644 index 7f134dc..0000000 --- a/evm/go-x1/utils/file.go +++ /dev/null @@ -1,54 +0,0 @@ -package utils - -import ( - "io/ioutil" - "os" - "path/filepath" - - "github.com/ethereum/go-ethereum/log" -) - -func OpenFile(path string, isSyncMode bool) *os.File { - const dirPerm = 0700 - if err := os.MkdirAll(filepath.Dir(path), dirPerm); err != nil { - log.Crit("Failed to create file dir", "file", path, "err", err) - } - sync := 0 - if isSyncMode { - sync = os.O_SYNC - } - fh, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|sync, 0666) - if err != nil { - log.Crit("Failed to open file", "file", path, "err", err) - } - return fh -} - -func FileExists(path string) bool { - _, err := os.Stat(path) - return err == nil -} - -func FilePut(path string, content []byte, isSyncMode bool) { - fh := OpenFile(path, isSyncMode) - defer fh.Close() - if err := fh.Truncate(0); err != nil { - log.Crit("Failed to truncate file", "file", path, "err", err) - } - if _, err := fh.Write(content); err != nil { - log.Crit("Failed to write to file", "file", path, "err", err) - } -} - -func FileGet(path string) []byte { - if !FileExists(path) { - return nil - } - fh, err := os.Open(path) - if err != nil { - log.Crit("Failed to open file", "file", path, "err", err) - } - defer fh.Close() - res, _ := ioutil.ReadAll(fh) - return res -} diff --git a/evm/go-x1/utils/iodb/io_db.go b/evm/go-x1/utils/iodb/io_db.go deleted file mode 100644 index c27755c..0000000 --- a/evm/go-x1/utils/iodb/io_db.go +++ /dev/null @@ -1,98 +0,0 @@ -package iodb - -import ( - "io" - - "github.com/Fantom-foundation/lachesis-base/common/bigendian" - "github.com/Fantom-foundation/lachesis-base/kvdb" - - "github.com/Fantom-foundation/go-opera/utils/ioread" -) - -func Write(writer io.Writer, it kvdb.Iterator) error { - for it.Next() { - _, err := writer.Write(bigendian.Uint32ToBytes(uint32(len(it.Key())))) - if err != nil { - return err - } - _, err = writer.Write(it.Key()) - if err != nil { - return err - } - _, err = writer.Write(bigendian.Uint32ToBytes(uint32(len(it.Value())))) - if err != nil { - return err - } - _, err = writer.Write(it.Value()) - if err != nil { - return err - } - } - return nil -} - -func NewIterator(reader io.Reader) kvdb.Iterator { - return &Iterator{ - reader: reader, - } -} - -type Iterator struct { - reader io.Reader - key, value []byte - err error -} - -func (it *Iterator) Next() bool { - if it.err != nil { - return false - } - var lenB [4]byte - it.err = ioread.ReadAll(it.reader, lenB[:]) - if it.err == io.EOF { - it.err = nil - return false - } - if it.err != nil { - return false - } - - lenKey := bigendian.BytesToUint32(lenB[:]) - key := make([]byte, lenKey) - it.err = ioread.ReadAll(it.reader, key) - if it.err != nil { - return false - } - - it.err = ioread.ReadAll(it.reader, lenB[:]) - if it.err != nil { - return false - } - - lenValue := bigendian.BytesToUint32(lenB[:]) - value := make([]byte, lenValue) - it.err = ioread.ReadAll(it.reader, value) - if it.err != nil { - return false - } - - it.key = key - it.value = value - return true -} - -func (it *Iterator) Error() error { - return it.err -} - -func (it *Iterator) Key() []byte { - return it.key -} - -func (it *Iterator) Value() []byte { - return it.value -} - -func (it *Iterator) Release() { - it.reader = nil -} diff --git a/evm/go-x1/utils/ioread/ioread.go b/evm/go-x1/utils/ioread/ioread.go deleted file mode 100644 index d2d6e03..0000000 --- a/evm/go-x1/utils/ioread/ioread.go +++ /dev/null @@ -1,17 +0,0 @@ -package ioread - -import "io" - -func ReadAll(reader io.Reader, buf []byte) error { - consumed := 0 - for { - n, err := reader.Read(buf[consumed:]) - consumed += n - if consumed == len(buf) { - return nil - } - if err != nil { - return err - } - } -} diff --git a/evm/go-x1/utils/memory/LICENSE b/evm/go-x1/utils/memory/LICENSE deleted file mode 100644 index 63ca4a6..0000000 --- a/evm/go-x1/utils/memory/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2017, Jeremy Jay -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/evm/go-x1/utils/memory/doc.go b/evm/go-x1/utils/memory/doc.go deleted file mode 100644 index 4e4f984..0000000 --- a/evm/go-x1/utils/memory/doc.go +++ /dev/null @@ -1,24 +0,0 @@ -// Package memory provides a single method reporting total system memory -// accessible to the kernel. -package memory - -// TotalMemory returns the total accessible system memory in bytes. -// -// The total accessible memory is installed physical memory size minus reserved -// areas for the kernel and hardware, if such reservations are reported by -// the operating system. -// -// If accessible memory size could not be determined, then 0 is returned. -func TotalMemory() uint64 { - return sysTotalMemory() -} - -// FreeMemory returns the total free system memory in bytes. -// -// The total free memory is installed physical memory size minus reserved -// areas for other applications running on the same system. -// -// If free memory size could not be determined, then 0 is returned. -func FreeMemory() uint64 { - return sysFreeMemory() -} diff --git a/evm/go-x1/utils/memory/memory_bsd.go b/evm/go-x1/utils/memory/memory_bsd.go deleted file mode 100644 index 7c4afa3..0000000 --- a/evm/go-x1/utils/memory/memory_bsd.go +++ /dev/null @@ -1,20 +0,0 @@ -//go:build freebsd || openbsd || dragonfly || netbsd -// +build freebsd openbsd dragonfly netbsd - -package memory - -func sysTotalMemory() uint64 { - s, err := sysctlUint64("hw.physmem") - if err != nil { - return 0 - } - return s -} - -func sysFreeMemory() uint64 { - s, err := sysctlUint64("hw.usermem") - if err != nil { - return 0 - } - return s -} diff --git a/evm/go-x1/utils/memory/memory_darwin.go b/evm/go-x1/utils/memory/memory_darwin.go deleted file mode 100644 index c4b604e..0000000 --- a/evm/go-x1/utils/memory/memory_darwin.go +++ /dev/null @@ -1,50 +0,0 @@ -//go:build darwin -// +build darwin - -package memory - -import ( - "os/exec" - "regexp" - "strconv" -) - -func sysTotalMemory() uint64 { - s, err := sysctlUint64("hw.memsize") - if err != nil { - return 0 - } - return s -} - -func sysFreeMemory() uint64 { - cmd := exec.Command("vm_stat") - outBytes, err := cmd.Output() - if err != nil { - return 0 - } - - rePageSize := regexp.MustCompile("page size of ([0-9]*) bytes") - reFreePages := regexp.MustCompile("Pages free: *([0-9]*)\\.") - - // default: page size of 4096 bytes - matches := rePageSize.FindSubmatchIndex(outBytes) - pageSize := uint64(4096) - if len(matches) == 4 { - pageSize, err = strconv.ParseUint(string(outBytes[matches[2]:matches[3]]), 10, 64) - if err != nil { - return 0 - } - } - - // ex: Pages free: 1126961. - matches = reFreePages.FindSubmatchIndex(outBytes) - freePages := uint64(0) - if len(matches) == 4 { - freePages, err = strconv.ParseUint(string(outBytes[matches[2]:matches[3]]), 10, 64) - if err != nil { - return 0 - } - } - return freePages * pageSize -} diff --git a/evm/go-x1/utils/memory/memory_linux.go b/evm/go-x1/utils/memory/memory_linux.go deleted file mode 100644 index ef1699f..0000000 --- a/evm/go-x1/utils/memory/memory_linux.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build linux -// +build linux - -package memory - -import "syscall" - -func sysTotalMemory() uint64 { - in := &syscall.Sysinfo_t{} - err := syscall.Sysinfo(in) - if err != nil { - return 0 - } - // If this is a 32-bit system, then these fields are - // uint32 instead of uint64. - // So we always convert to uint64 to match signature. - return uint64(in.Totalram) * uint64(in.Unit) -} - -func sysFreeMemory() uint64 { - in := &syscall.Sysinfo_t{} - err := syscall.Sysinfo(in) - if err != nil { - return 0 - } - // If this is a 32-bit system, then these fields are - // uint32 instead of uint64. - // So we always convert to uint64 to match signature. - return uint64(in.Freeram) * uint64(in.Unit) -} diff --git a/evm/go-x1/utils/memory/memory_test.go b/evm/go-x1/utils/memory/memory_test.go deleted file mode 100644 index 6ceb35c..0000000 --- a/evm/go-x1/utils/memory/memory_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package memory - -import "testing" - -func TestNonZero(t *testing.T) { - if TotalMemory() == 0 { - t.Fatal("TotalMemory returned 0") - } - if FreeMemory() == 0 { - t.Fatal("FreeMemory returned 0") - } -} diff --git a/evm/go-x1/utils/memory/memory_windows.go b/evm/go-x1/utils/memory/memory_windows.go deleted file mode 100644 index b4bfe3f..0000000 --- a/evm/go-x1/utils/memory/memory_windows.go +++ /dev/null @@ -1,61 +0,0 @@ -//go:build windows -// +build windows - -package memory - -import ( - "syscall" - "unsafe" -) - -// omitting a few fields for brevity... -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx -type memStatusEx struct { - dwLength uint32 - dwMemoryLoad uint32 - ullTotalPhys uint64 - ullAvailPhys uint64 - unused [5]uint64 -} - -func sysTotalMemory() uint64 { - kernel32, err := syscall.LoadDLL("kernel32.dll") - if err != nil { - return 0 - } - // GetPhysicallyInstalledSystemMemory is simpler, but broken on - // older versions of windows (and uses this under the hood anyway). - globalMemoryStatusEx, err := kernel32.FindProc("GlobalMemoryStatusEx") - if err != nil { - return 0 - } - msx := &memStatusEx{ - dwLength: 64, - } - r, _, _ := globalMemoryStatusEx.Call(uintptr(unsafe.Pointer(msx))) - if r == 0 { - return 0 - } - return msx.ullTotalPhys -} - -func sysFreeMemory() uint64 { - kernel32, err := syscall.LoadDLL("kernel32.dll") - if err != nil { - return 0 - } - // GetPhysicallyInstalledSystemMemory is simpler, but broken on - // older versions of windows (and uses this under the hood anyway). - globalMemoryStatusEx, err := kernel32.FindProc("GlobalMemoryStatusEx") - if err != nil { - return 0 - } - msx := &memStatusEx{ - dwLength: 64, - } - r, _, _ := globalMemoryStatusEx.Call(uintptr(unsafe.Pointer(msx))) - if r == 0 { - return 0 - } - return msx.ullAvailPhys -} diff --git a/evm/go-x1/utils/memory/memsysctl.go b/evm/go-x1/utils/memory/memsysctl.go deleted file mode 100644 index 7b3fcc3..0000000 --- a/evm/go-x1/utils/memory/memsysctl.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build darwin || freebsd || openbsd || dragonfly || netbsd -// +build darwin freebsd openbsd dragonfly netbsd - -package memory - -import ( - "syscall" - "unsafe" -) - -func sysctlUint64(name string) (uint64, error) { - s, err := syscall.Sysctl(name) - if err != nil { - return 0, err - } - // hack because the string conversion above drops a \0 - b := []byte(s) - if len(b) < 8 { - b = append(b, 0) - } - return *(*uint64)(unsafe.Pointer(&b[0])), nil -} diff --git a/evm/go-x1/utils/memory/stub.go b/evm/go-x1/utils/memory/stub.go deleted file mode 100644 index 92e8f00..0000000 --- a/evm/go-x1/utils/memory/stub.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build !linux && !darwin && !windows && !freebsd && !dragonfly && !netbsd && !openbsd -// +build !linux,!darwin,!windows,!freebsd,!dragonfly,!netbsd,!openbsd - -package memory - -func sysTotalMemory() uint64 { - return 0 -} -func sysFreeMemory() uint64 { - return 0 -} diff --git a/evm/go-x1/utils/migration/id_store.go b/evm/go-x1/utils/migration/id_store.go deleted file mode 100644 index 876b227..0000000 --- a/evm/go-x1/utils/migration/id_store.go +++ /dev/null @@ -1,19 +0,0 @@ -package migration - -// IDStore interface for stores id in migrations -type IDStore interface { - GetID() string - SetID(string) -} - -type inmemIDStore struct { - lastID string -} - -func (p *inmemIDStore) GetID() string { - return string(p.lastID) -} - -func (p *inmemIDStore) SetID(id string) { - p.lastID = id -} diff --git a/evm/go-x1/utils/migration/kvdb_id_store.go b/evm/go-x1/utils/migration/kvdb_id_store.go deleted file mode 100644 index c807102..0000000 --- a/evm/go-x1/utils/migration/kvdb_id_store.go +++ /dev/null @@ -1,41 +0,0 @@ -package migration - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/log" -) - -// KvdbIDStore stores id -type KvdbIDStore struct { - table kvdb.Store - key []byte -} - -// NewKvdbIDStore constructor -func NewKvdbIDStore(table kvdb.Store) *KvdbIDStore { - return &KvdbIDStore{ - table: table, - key: []byte("id"), - } -} - -// GetID is a getter -func (p *KvdbIDStore) GetID() string { - id, err := p.table.Get(p.key) - if err != nil { - log.Crit("Failed to get key-value", "err", err) - } - - if id == nil { - return "" - } - return string(id) -} - -// SetID is a setter -func (p *KvdbIDStore) SetID(id string) { - err := p.table.Put(p.key, []byte(id)) - if err != nil { - log.Crit("Failed to put key-value", "err", err) - } -} diff --git a/evm/go-x1/utils/migration/migration.go b/evm/go-x1/utils/migration/migration.go deleted file mode 100644 index b936ea1..0000000 --- a/evm/go-x1/utils/migration/migration.go +++ /dev/null @@ -1,99 +0,0 @@ -package migration - -import ( - "crypto/sha256" - "errors" - "fmt" - - "github.com/ethereum/go-ethereum/log" -) - -// Migration is a migration step. -type Migration struct { - name string - exec func() error - prev *Migration -} - -// Begin with empty unique migration step. -func Begin(appName string) *Migration { - return &Migration{ - name: appName, - } -} - -// Next creates next migration. -func (m *Migration) Next(name string, exec func() error) *Migration { - if name == "" { - panic("empty name") - } - - if exec == nil { - panic("empty exec") - } - - return &Migration{ - name: name, - exec: exec, - prev: m, - } -} - -func idOf(name string) string { - digest := sha256.New() - digest.Write([]byte(name)) - - bytes := digest.Sum(nil) - return fmt.Sprintf("%x", bytes) -} - -// ID is an uniq migration's id. -func (m *Migration) ID() string { - return idOf(m.name) -} - -// Exec method run migrations chain in order -func (m *Migration) Exec(curr IDStore, flush func() error) error { - currID := curr.GetID() - myID := m.ID() - - if m.veryFirst() { - if currID != myID { - return errors.New("unknown version: " + currID) - } - return nil - } - - if currID == myID { - return nil - } - - err := m.prev.Exec(curr, flush) - if err != nil { - return err - } - - log.Warn("Applying migration", "name", m.name) - err = m.exec() - if err != nil { - log.Error("'"+m.name+"' migration failed", "err", err) - return err - } - - curr.SetID(myID) - - return flush() -} - -func (m *Migration) veryFirst() bool { - return m.exec == nil -} - -// IDs return list of migrations ids in chain -func (m *Migration) IDs() []string { - if m.prev == nil { - return []string{m.ID()} - } - - return append(m.prev.IDs(), m.ID()) -} diff --git a/evm/go-x1/utils/migration/migration_test.go b/evm/go-x1/utils/migration/migration_test.go deleted file mode 100644 index 1b11be5..0000000 --- a/evm/go-x1/utils/migration/migration_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package migration - -import ( - "errors" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestMigrations(t *testing.T) { - testData := map[string]int{} - curVer := &inmemIDStore{} - - t.Run("native", func(t *testing.T) { - require := require.New(t) - - native := Begin("native") - curVer.lastID = idOf("native") - - num := 1 - lastGood := native.Next("01", - func() error { - testData["migration1"] = num - num++ - return nil - }, - ).Next("02", - func() error { - testData["migration2"] = num - num++ - return nil - }, - ) - - afterBad := lastGood.Next("03", - func() error { - testData["migration3"] = num - num++ - return errors.New("test migration error") - }, - ).Next("04", - func() error { - testData["migration4"] = num - num++ - return nil - }, - ) - - err := afterBad.Exec(curVer, flush) - require.Error(err, "Success after a migration error") - - lastID := curVer.GetID() - require.Equal(lastGood.ID(), lastID, "Bad last id in idProducer after a migration error") - - require.Equal(1, testData["migration1"], "Bad value after run migration1") - require.Equal(2, testData["migration2"], "Bad value after run migration2") - require.Equal(3, testData["migration3"], "Bad value after run migration3") - require.Empty(testData["migration4"], "Bad data for migration4 - should by empty") - - // Continue with fixed transactions - - num = 3 - fixed := lastGood.Next("03", - func() error { - testData["migration3"] = num - num++ - return nil - }, - ).Next("04", - func() error { - testData["migration4"] = num - num++ - return nil - }, - ) - - err = fixed.Exec(curVer, flush) - require.NoError(err, "Error when run migration manager") - - require.Equal(1, testData["migration1"], "Bad value after run migration1") - require.Equal(2, testData["migration2"], "Bad value after run migration2") - require.Equal(3, testData["migration3"], "Bad value after run migration3") - require.Equal(4, testData["migration4"], "Bad value after run migration4") - }) - - t.Run("nonnative", func(t *testing.T) { - require := require.New(t) - - nonnative := Begin("nonnative"). - Next("01", - func() error { - testData["migration1"] = 999 - return nil - }, - ) - - err := nonnative.Exec(curVer, flush) - require.NotEqual(999, testData["migration1"], "nonnative migration is applied") - require.Error(err) - }) -} - -func flush() error { - return nil -} diff --git a/evm/go-x1/utils/nameof.go b/evm/go-x1/utils/nameof.go deleted file mode 100644 index f42fa55..0000000 --- a/evm/go-x1/utils/nameof.go +++ /dev/null @@ -1,17 +0,0 @@ -package utils - -import ( - "fmt" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" -) - -// NameOf returns human readable string representation. -func NameOf(p idx.ValidatorID) string { - if name := hash.GetNodeName(p); len(name) > 0 { - return name - } - - return fmt.Sprintf("%d", p) -} diff --git a/evm/go-x1/utils/num_queue.go b/evm/go-x1/utils/num_queue.go deleted file mode 100644 index 65dd1bd..0000000 --- a/evm/go-x1/utils/num_queue.go +++ /dev/null @@ -1,55 +0,0 @@ -package utils - -import ( - "sync" -) - -type NumQueue struct { - mu sync.Mutex - lastDone uint64 - waiters []chan struct{} -} - -func NewNumQueue(init uint64) *NumQueue { - return &NumQueue{ - lastDone: init, - } -} - -func (q *NumQueue) Done(n uint64) { - q.mu.Lock() - defer q.mu.Unlock() - - if n <= q.lastDone { - panic("Already done!") - } - - pos := int(n - q.lastDone - 1) - for i := 0; i < len(q.waiters) && i <= pos; i++ { - close(q.waiters[i]) - } - if pos < len(q.waiters) { - q.waiters = q.waiters[pos+1:] - } else { - q.waiters = make([]chan struct{}, 0, 1000) - } - - q.lastDone = n -} - -func (q *NumQueue) WaitFor(n uint64) { - q.mu.Lock() - - if n <= q.lastDone { - q.mu.Unlock() - return - } - - count := int(n - q.lastDone) - for i := len(q.waiters); i < count; i++ { - q.waiters = append(q.waiters, make(chan struct{})) - } - ch := q.waiters[count-1] - q.mu.Unlock() - <-ch -} diff --git a/evm/go-x1/utils/num_queue_test.go b/evm/go-x1/utils/num_queue_test.go deleted file mode 100644 index 71c10fc..0000000 --- a/evm/go-x1/utils/num_queue_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package utils - -import ( - "math/rand" - "sync" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNumQueue(t *testing.T) { - - t.Run("Simple", func(t *testing.T) { - N := uint64(100) - q := NewNumQueue(0) - for i := uint64(1); i <= N; i++ { - var iter sync.WaitGroup - iter.Add(1) - go func(i uint64) { - defer iter.Done() - q.WaitFor(i) - }(i) - - q.Done(i) - iter.Wait() - } - }) - - t.Run("Random", func(t *testing.T) { - require := require.New(t) - N := 100 - - q := NewNumQueue(0) - output := make(chan uint64, 10) - nums := rand.Perm(N) - - for _, n := range nums { - go func(n uint64) { - q.WaitFor(n - 1) - output <- n - if n == uint64(N) { - close(output) - } - q.Done(n) - - }(uint64(n + 1)) - } - - var prev uint64 - for got := range output { - require.Less(prev, got) - prev = got - } - }) -} diff --git a/evm/go-x1/utils/pretty_duration.go b/evm/go-x1/utils/pretty_duration.go deleted file mode 100644 index 9ed1a52..0000000 --- a/evm/go-x1/utils/pretty_duration.go +++ /dev/null @@ -1,54 +0,0 @@ -package utils - -import ( - "fmt" - "time" - - "github.com/ethereum/go-ethereum/common" -) - -// PrettyDuration is a combination of common.PrettyDuration and common.PrettyAge -// It is a pretty printed version of a time.Duration value that rounds -// the values up to a single most significant unit, -// while showing the least significant part if duration isn't too large. -type PrettyDuration time.Duration - -// ageUnits is a list of units the age pretty printing uses. -var ageUnits = []struct { - Size time.Duration - Symbol string -}{ - {12 * 30 * 24 * time.Hour, "y"}, - {30 * 24 * time.Hour, "mo"}, - {24 * time.Hour, "d"}, - {time.Hour, "h"}, - {time.Minute, "m"}, -} - -// String implements the Stringer interface, allowing pretty printing of duration -// values rounded to the most significant time unit. -func (t PrettyDuration) String() string { - // Calculate the time difference and handle the 0 cornercase - diff := time.Duration(t) - // Accumulate a precision of 3 components before returning - result, prec := "", 0 - if diff < 0 { - diff = -diff - result = "-" - } - - for _, unit := range ageUnits { - if diff > unit.Size { - result = fmt.Sprintf("%s%d%s", result, diff/unit.Size, unit.Symbol) - diff %= unit.Size - - if prec += 1; prec >= 3 { - break - } - } - } - if prec < 3 { - return fmt.Sprintf("%s%s", result, common.PrettyDuration(diff).String()) - } - return result -} diff --git a/evm/go-x1/utils/pretty_duration_test.go b/evm/go-x1/utils/pretty_duration_test.go deleted file mode 100644 index a3732ee..0000000 --- a/evm/go-x1/utils/pretty_duration_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package utils - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestPrettyDuration_String(t *testing.T) { - for _, testcase := range []struct { - str string - val time.Duration - }{ - {"0s", 0}, - {"1ns", time.Nanosecond}, - {"1µs", time.Microsecond}, - {"1ms", time.Millisecond}, - {"1s", time.Second}, - {"1.000s", time.Second + time.Microsecond + time.Nanosecond}, - {"1.001s", time.Second + time.Millisecond + time.Microsecond + time.Nanosecond}, - {"1m1.001s", time.Minute + time.Second + time.Millisecond + time.Microsecond + time.Nanosecond}, - {"1h1m1.001s", time.Hour + time.Minute + time.Second + time.Millisecond + time.Microsecond + time.Nanosecond}, - {"1d1h1m", 24*time.Hour + time.Hour + time.Minute + time.Second + time.Millisecond + time.Microsecond + time.Nanosecond}, - {"1mo1d1h", 30*24*time.Hour + 24*time.Hour + time.Hour + time.Minute + time.Second + time.Millisecond + time.Microsecond + time.Nanosecond}, - {"26y4mo23d", time.Duration(9503.123456789 * 24 * float64(time.Hour))}, - } { - require.Equal(t, testcase.str, PrettyDuration(testcase.val).String()) - if testcase.val > 0 { - require.Equal(t, "-"+testcase.str, PrettyDuration(-testcase.val).String()) - } - } -} diff --git a/evm/go-x1/utils/randat/rand_at.go b/evm/go-x1/utils/randat/rand_at.go deleted file mode 100644 index 59e29d7..0000000 --- a/evm/go-x1/utils/randat/rand_at.go +++ /dev/null @@ -1,26 +0,0 @@ -package randat - -import ( - "math/rand" -) - -type cached struct { - seed uint64 - r uint64 -} - -var ( - gSeed = rand.Int63() - cache = cached{} -) - -// RandAt returns random number with seed -// Not safe for concurrent use -func RandAt(seed uint64) uint64 { - if seed != 0 && cache.seed == seed { - return cache.r - } - cache.seed = seed - cache.r = rand.New(rand.NewSource(gSeed ^ int64(seed))).Uint64() - return cache.r -} diff --git a/evm/go-x1/utils/rate/gauge.go b/evm/go-x1/utils/rate/gauge.go deleted file mode 100644 index 6a13a57..0000000 --- a/evm/go-x1/utils/rate/gauge.go +++ /dev/null @@ -1,80 +0,0 @@ -package rate - -import ( - "sync/atomic" - - "github.com/ethereum/go-ethereum/metrics" -) - -// Gauge represents an exponentially-weighted moving average of given values -type Gauge struct { - input metrics.Meter - count metrics.Meter - max int64 -} - -// NewGauge constructs a new Gauge and launches a goroutine. -// Be sure to call Stop() once the meter is of no use to allow for garbage collection. -func NewGauge() *Gauge { - return &Gauge{ - input: metrics.NewMeterForced(), - count: metrics.NewMeterForced(), - } -} - -// Mark records the the current value of the gauge. -func (g *Gauge) Mark(v int64) { - g.input.Mark(v) - g.count.Mark(1) - //// maintain maximum input value in a thread-safe way - for max := g.getMax(); max < v && !atomic.CompareAndSwapInt64(&g.max, max, v); { - max = g.getMax() - } -} - -func (g *Gauge) getMax() int64 { - return atomic.LoadInt64(&g.max) -} - -func (g *Gauge) rateToGauge(valuesSum, calls float64) float64 { - if calls < 0.000001 { - return 0 - } - gaugeValue := valuesSum / calls - // gaugeValue cannot be larger than a maximum input value - max := float64(g.getMax()) - if gaugeValue > max { - return max - } - return gaugeValue -} - -// Rate1 returns the one-minute moving average of the gauge values. -// Cannot be larger than max(largest input value, 0) -func (g *Gauge) Rate1() float64 { - return g.rateToGauge(g.input.Rate1(), g.count.Rate1()) -} - -// Rate5 returns the five-minute moving average of the gauge values. -// Cannot be larger than max(largest input value, 0) -func (g *Gauge) Rate5() float64 { - return g.rateToGauge(g.input.Rate5(), g.count.Rate5()) -} - -// Rate15 returns the fifteen-minute moving average of the gauge values. -// Cannot be larger than max(largest input value, 0) -func (g *Gauge) Rate15() float64 { - return g.rateToGauge(g.input.Rate15(), g.count.Rate15()) -} - -// RateMean returns the gauge's mean value. -// Cannot be larger than max(largest input value, 0) -func (g *Gauge) RateMean() float64 { - return g.rateToGauge(g.input.RateMean(), g.count.RateMean()) -} - -// Stop stops the gauge -func (g *Gauge) Stop() { - g.input.Stop() - g.count.Stop() -} diff --git a/evm/go-x1/utils/rate/gauge_test.go b/evm/go-x1/utils/rate/gauge_test.go deleted file mode 100644 index 486359e..0000000 --- a/evm/go-x1/utils/rate/gauge_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package rate - -import ( - "sync" - "testing" -) - -func TestGauge_Concurrency(t *testing.T) { - for try := 0; try < 100; try++ { - testGaugeConcurrency(t) - } -} - -func testGaugeConcurrency(t *testing.T) { - g := NewGauge() - barrier := make(chan struct{}) - wg := sync.WaitGroup{} - end := int64(32) - for i := int64(0); i <= end; i++ { - wg.Add(1) - turn := i - go func() { - defer wg.Done() - select { - case <-barrier: - g.Mark(turn) - if v := int64(g.rateToGauge(float64(2*end), 1)); v < turn { - t.Errorf("%d >= %d", v, end) - } - return - } - }() - } - close(barrier) - wg.Wait() - if v := int64(g.rateToGauge(float64(2*end), 1)); v != end { - t.Errorf("%d != %d", v, end) - } -} diff --git a/evm/go-x1/utils/rlpstore/rlpstore.go b/evm/go-x1/utils/rlpstore/rlpstore.go deleted file mode 100644 index 653c656..0000000 --- a/evm/go-x1/utils/rlpstore/rlpstore.go +++ /dev/null @@ -1,40 +0,0 @@ -package rlpstore - -import ( - "github.com/Fantom-foundation/go-opera/logger" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/ethereum/go-ethereum/rlp" -) - -type Helper struct { - logger.Instance -} - -// Set RLP value -func (s *Helper) Set(table kvdb.Store, key []byte, val interface{}) { - buf, err := rlp.EncodeToBytes(val) - if err != nil { - s.Log.Crit("Failed to encode rlp", "err", err) - } - - if err := table.Put(key, buf); err != nil { - s.Log.Crit("Failed to put key-value", "err", err) - } -} - -// Get RLP value -func (s *Helper) Get(table kvdb.Store, key []byte, to interface{}) interface{} { - buf, err := table.Get(key) - if err != nil { - s.Log.Crit("Failed to get key-value", "err", err) - } - if buf == nil { - return nil - } - - err = rlp.DecodeBytes(buf, to) - if err != nil { - s.Log.Crit("Failed to decode rlp", "err", err, "size", len(buf)) - } - return to -} diff --git a/evm/go-x1/utils/self-table.go b/evm/go-x1/utils/self-table.go deleted file mode 100644 index f6ce2cd..0000000 --- a/evm/go-x1/utils/self-table.go +++ /dev/null @@ -1,13 +0,0 @@ -package utils - -import ( - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" -) - -func NewTableOrSelf(db kvdb.Store, prefix []byte) kvdb.Store { - if len(prefix) == 0 { - return db - } - return table.New(db, prefix) -} diff --git a/evm/go-x1/utils/signers/gsignercache/global_cache.go b/evm/go-x1/utils/signers/gsignercache/global_cache.go deleted file mode 100644 index 2b86478..0000000 --- a/evm/go-x1/utils/signers/gsignercache/global_cache.go +++ /dev/null @@ -1,32 +0,0 @@ -package gsignercache - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - lru "github.com/hashicorp/golang-lru" -) - -var ( - globalCache, _ = lru.New(40000) -) - -type WlruCache struct { - Cache *lru.Cache -} - -func (w *WlruCache) Add(txid common.Hash, c types.CachedSender) { - w.Cache.Add(txid, c) -} - -func (w *WlruCache) Get(txid common.Hash) *types.CachedSender { - ic, ok := w.Cache.Get(txid) - if !ok { - return nil - } - c := ic.(types.CachedSender) - return &c -} - -func Wrap(signer types.Signer) types.Signer { - return types.WrapWithCachedSigner(signer, &WlruCache{globalCache}) -} diff --git a/evm/go-x1/utils/signers/internaltx/internaltx.go b/evm/go-x1/utils/signers/internaltx/internaltx.go deleted file mode 100644 index d65b289..0000000 --- a/evm/go-x1/utils/signers/internaltx/internaltx.go +++ /dev/null @@ -1,23 +0,0 @@ -package internaltx - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -func IsInternal(tx *types.Transaction) bool { - v, r, _ := tx.RawSignatureValues() - return v.Sign() == 0 && r.Sign() == 0 -} - -func InternalSender(tx *types.Transaction) common.Address { - _, _, s := tx.RawSignatureValues() - return common.BytesToAddress(s.Bytes()) -} - -func Sender(signer types.Signer, tx *types.Transaction) (common.Address, error) { - if !IsInternal(tx) { - return types.Sender(signer, tx) - } - return InternalSender(tx), nil -} diff --git a/evm/go-x1/utils/signers/internaltx/internaltx_test.go b/evm/go-x1/utils/signers/internaltx/internaltx_test.go deleted file mode 100644 index 4407c3a..0000000 --- a/evm/go-x1/utils/signers/internaltx/internaltx_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package internaltx - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/status-im/keycard-go/hexutils" - "github.com/stretchr/testify/require" -) - -func TestIsInternal(t *testing.T) { - require.True(t, IsInternal(types.NewTx(&types.LegacyTx{ - V: new(big.Int), - R: new(big.Int), - S: new(big.Int), - }))) - require.True(t, IsInternal(types.NewTx(&types.DynamicFeeTx{ - V: new(big.Int), - R: new(big.Int), - S: new(big.Int), - }))) - require.True(t, IsInternal(types.NewTx(&types.LegacyTx{ - V: new(big.Int), - R: new(big.Int), - S: big.NewInt(1), - }))) - require.True(t, IsInternal(types.NewTx(&types.LegacyTx{ - V: new(big.Int), - R: new(big.Int), - S: new(big.Int).SetBytes(hexutils.HexToBytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), - }))) - require.False(t, IsInternal(types.NewTx(&types.LegacyTx{ - V: big.NewInt(1), - R: big.NewInt(1), - S: big.NewInt(1), - }))) - require.False(t, IsInternal(types.NewTx(&types.DynamicFeeTx{ - V: big.NewInt(1), - R: big.NewInt(1), - S: big.NewInt(1), - }))) - require.False(t, IsInternal(types.NewTx(&types.LegacyTx{ - V: big.NewInt(1), - R: new(big.Int), - S: new(big.Int), - }))) - require.False(t, IsInternal(types.NewTx(&types.LegacyTx{ - V: new(big.Int), - R: big.NewInt(1), - S: new(big.Int), - }))) -} - -func TestInternalSender(t *testing.T) { - require.Equal(t, common.Address{}, InternalSender(types.NewTx(&types.LegacyTx{ - V: new(big.Int), - R: new(big.Int), - S: new(big.Int), - }))) - example := common.HexToAddress("0x0000000000000000000000000000000000000001") - require.Equal(t, example, InternalSender(types.NewTx(&types.LegacyTx{ - V: new(big.Int), - R: new(big.Int), - S: new(big.Int).SetBytes(example.Bytes()), - }))) - example = common.HexToAddress("0x0000000000000000000000000000000000000100") - require.Equal(t, example, InternalSender(types.NewTx(&types.LegacyTx{ - V: new(big.Int), - R: new(big.Int), - S: new(big.Int).SetBytes(example.Bytes()), - }))) - example = common.HexToAddress("0x1000000000000000000000000000000000000000") - require.Equal(t, example, InternalSender(types.NewTx(&types.LegacyTx{ - V: new(big.Int), - R: new(big.Int), - S: new(big.Int).SetBytes(example.Bytes()), - }))) - example = common.HexToAddress("0x1000000000000000000000000000000000000001") - require.Equal(t, example, InternalSender(types.NewTx(&types.LegacyTx{ - V: new(big.Int), - R: new(big.Int), - S: new(big.Int).SetBytes(example.Bytes()), - }))) -} diff --git a/evm/go-x1/utils/spin_lock.go b/evm/go-x1/utils/spin_lock.go deleted file mode 100644 index ddfc511..0000000 --- a/evm/go-x1/utils/spin_lock.go +++ /dev/null @@ -1,37 +0,0 @@ -package utils - -import ( - "runtime" - "sync/atomic" -) - -// SpinLock implements a simple atomic spin lock, the zero value for a SpinLock is an unlocked spinlock. -type SpinLock struct { - f uint32 -} - -// Lock locks sl. If the lock is already in use, the caller blocks until Unlock is called -func (sl *SpinLock) Lock() { - for !sl.TryLock() { - runtime.Gosched() // allow other goroutines to do work. - } -} - -// Unlock unlocks sl, unlike [Mutex.Unlock](http://golang.org/pkg/sync/#Mutex.Unlock), -// there's no harm calling it on an unlocked SpinLock -func (sl *SpinLock) Unlock() { - atomic.StoreUint32(&sl.f, 0) -} - -// TryLock will try to lock sl and return whether it succeed or not without blocking. -func (sl *SpinLock) TryLock() bool { - return atomic.CompareAndSwapUint32(&sl.f, 0, 1) -} - -// String is human readable lock state -func (sl *SpinLock) String() string { - if atomic.LoadUint32(&sl.f) == 1 { - return "Locked" - } - return "Unlocked" -} diff --git a/evm/go-x1/utils/to_ftm.go b/evm/go-x1/utils/to_ftm.go deleted file mode 100644 index d291812..0000000 --- a/evm/go-x1/utils/to_ftm.go +++ /dev/null @@ -1,8 +0,0 @@ -package utils - -import "math/big" - -// ToFtm number of FTM to Wei -func ToFtm(ftm uint64) *big.Int { - return new(big.Int).Mul(new(big.Int).SetUint64(ftm), big.NewInt(1e18)) -} diff --git a/evm/go-x1/utils/txtime/txtime.go b/evm/go-x1/utils/txtime/txtime.go deleted file mode 100644 index 9ccc72c..0000000 --- a/evm/go-x1/utils/txtime/txtime.go +++ /dev/null @@ -1,49 +0,0 @@ -package txtime - -import ( - "time" - - "github.com/Fantom-foundation/lachesis-base/utils/wlru" - "github.com/ethereum/go-ethereum/common" -) - -var ( - globalFinalized, _ = wlru.New(30000, 30000) - globalNonFinalized, _ = wlru.New(5000, 5000) - Enabled = false -) - -func Saw(txid common.Hash, t time.Time) { - if !Enabled { - return - } - globalNonFinalized.ContainsOrAdd(txid, t, 1) -} - -func Validated(txid common.Hash, t time.Time) { - if !Enabled { - return - } - v, has := globalNonFinalized.Peek(txid) - if has { - t = v.(time.Time) - } - globalFinalized.ContainsOrAdd(txid, t, 1) -} - -func Of(txid common.Hash) time.Time { - if !Enabled { - return time.Time{} - } - v, has := globalFinalized.Get(txid) - if has { - return v.(time.Time) - } - v, has = globalNonFinalized.Get(txid) - if has { - return v.(time.Time) - } - now := time.Now() - Saw(txid, now) - return now -} diff --git a/evm/go-x1/utils/uint2hash.go b/evm/go-x1/utils/uint2hash.go deleted file mode 100644 index 445fdfb..0000000 --- a/evm/go-x1/utils/uint2hash.go +++ /dev/null @@ -1,27 +0,0 @@ -package utils - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -// BigTo256 converts big number to 32 bytes array -func BigTo256(b *big.Int) common.Hash { - return common.BytesToHash(b.Bytes()) -} - -// U64to256 converts uint64 to 32 bytes array -func U64to256(u64 uint64) common.Hash { - return BigTo256(new(big.Int).SetUint64(u64)) -} - -// U64toBig converts uint64 to big number -func U64toBig(u64 uint64) *big.Int { - return new(big.Int).SetUint64(u64) -} - -// I64to256 converts int64 to 32 bytes array -func I64to256(i64 int64) common.Hash { - return BigTo256(new(big.Int).SetInt64(i64)) -} diff --git a/evm/go-x1/utils/weighted_shuffle.go b/evm/go-x1/utils/weighted_shuffle.go deleted file mode 100644 index 5160295..0000000 --- a/evm/go-x1/utils/weighted_shuffle.go +++ /dev/null @@ -1,110 +0,0 @@ -package utils - -import ( - "crypto/sha256" - - "github.com/Fantom-foundation/lachesis-base/common/littleendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/pos" -) - -type weightedShuffleNode struct { - thisWeight pos.Weight - leftWeight pos.Weight - rightWeight pos.Weight -} - -type weightedShuffleTree struct { - seed hash.Hash - seedIndex int - - weights []pos.Weight - nodes []weightedShuffleNode -} - -func (t *weightedShuffleTree) leftIndex(i int) int { - return i*2 + 1 -} - -func (t *weightedShuffleTree) rightIndex(i int) int { - return i*2 + 2 -} - -func (t *weightedShuffleTree) build(i int) pos.Weight { - if i >= len(t.weights) { - return 0 - } - thisW := t.weights[i] - leftW := t.build(t.leftIndex(i)) - rightW := t.build(t.rightIndex(i)) - - if thisW <= 0 { - panic("all the weight must be positive") - } - - t.nodes[i] = weightedShuffleNode{ - thisWeight: thisW, - leftWeight: leftW, - rightWeight: rightW, - } - return thisW + leftW + rightW -} - -func (t *weightedShuffleTree) rand32() uint32 { - if t.seedIndex == 32 { - hasher := sha256.New() // use sha2 instead of sha3 for speed - hasher.Write(t.seed.Bytes()) - t.seed = hash.BytesToHash(hasher.Sum(nil)) - t.seedIndex = 0 - } - // use not used parts of old seed, instead of calculating new one - res := littleendian.BytesToUint32(t.seed[t.seedIndex : t.seedIndex+4]) - t.seedIndex += 4 - return res -} - -func (t *weightedShuffleTree) retrieve(i int) int { - node := t.nodes[i] - total := node.rightWeight + node.leftWeight + node.thisWeight - - r := pos.Weight(t.rand32()) % total - - if r < node.thisWeight { - t.nodes[i].thisWeight = 0 - return i - } else if r < node.thisWeight+node.leftWeight { - chosen := t.retrieve(t.leftIndex(i)) - t.nodes[i].leftWeight -= t.weights[chosen] - return chosen - } else { - chosen := t.retrieve(t.rightIndex(i)) - t.nodes[i].rightWeight -= t.weights[chosen] - return chosen - } -} - -// WeightedPermutation builds weighted random permutation -// Returns first {size} entries of {weights} permutation. -// Call with {size} == len(weights) to get the whole permutation. -func WeightedPermutation(size int, weights []pos.Weight, seed hash.Hash) []int { - if len(weights) < size { - panic("the permutation size must be less or equal to weights size") - } - - if len(weights) == 0 { - return make([]int, 0) - } - - tree := weightedShuffleTree{ - weights: weights, - nodes: make([]weightedShuffleNode, len(weights)), - seed: seed, - } - tree.build(0) - - permutation := make([]int, size) - for i := 0; i < size; i++ { - permutation[i] = tree.retrieve(0) - } - return permutation -} diff --git a/evm/go-x1/utils/weighted_shuffle_test.go b/evm/go-x1/utils/weighted_shuffle_test.go deleted file mode 100644 index 96c268f..0000000 --- a/evm/go-x1/utils/weighted_shuffle_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package utils - -import ( - "crypto/sha256" - "testing" - - "github.com/Fantom-foundation/lachesis-base/common/littleendian" - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/stretchr/testify/assert" -) - -func getTestWeightsIncreasing(num int) []pos.Weight { - weights := make([]pos.Weight, num) - for i := 0; i < num; i++ { - weights[i] = pos.Weight(i+1) * 1000 - } - return weights -} - -func getTestWeightsEqual(num int) []pos.Weight { - weights := make([]pos.Weight, num) - for i := 0; i < num; i++ { - weights[i] = 1000 - } - return weights -} - -// Test average distribution of the shuffle -func Test_Permutation_distribution(t *testing.T) { - weightsArr := getTestWeightsIncreasing(30) - - weightHits := make(map[int]int) // weight -> number of occurrences - for roundSeed := 0; roundSeed < 3000; roundSeed++ { - seed := hashOf(hash.Hash{}, uint32(roundSeed)) - perm := WeightedPermutation(len(weightsArr)/10, weightsArr, seed) - for _, p := range perm { - weight := weightsArr[p] - weightFactor := int(weight / 1000) - - _, ok := weightHits[weightFactor] - if !ok { - weightHits[weightFactor] = 0 - } - weightHits[weightFactor]++ - } - } - - assertar := assert.New(t) - for weightFactor, hits := range weightHits { - //fmt.Printf("Test_RandomElection_distribution: %d \n", hits/weightFactor) - assertar.Equal((hits/weightFactor) > 20-8, true) - assertar.Equal((hits/weightFactor) < 20+8, true) - if t.Failed() { - return - } - } -} - -// test that WeightedPermutation provides a correct permaition -func testCorrectPermutation(t *testing.T, weightsArr []pos.Weight) { - assertar := assert.New(t) - - perm := WeightedPermutation(len(weightsArr), weightsArr, hash.Hash{}) - assertar.Equal(len(weightsArr), len(perm)) - - met := make(map[int]bool) - for _, p := range perm { - assertar.True(p >= 0) - assertar.True(p < len(weightsArr)) - assertar.False(met[p]) - met[p] = true - } -} - -func Test_Permutation_correctness(t *testing.T) { - testCorrectPermutation(t, getTestWeightsIncreasing(1)) - testCorrectPermutation(t, getTestWeightsIncreasing(30)) - testCorrectPermutation(t, getTestWeightsEqual(1000)) -} - -func hashOf(a hash.Hash, b uint32) hash.Hash { - hasher := sha256.New() - hasher.Write(a.Bytes()) - hasher.Write(littleendian.Uint32ToBytes(uint32(b))) - return hash.FromBytes(hasher.Sum(nil)) -} - -func Test_Permutation_determinism(t *testing.T) { - weightsArr := getTestWeightsIncreasing(5) - - assertar := assert.New(t) - - assertar.Equal([]int{4, 0, 1, 2, 3}, WeightedPermutation(len(weightsArr), weightsArr, hashOf(hash.Hash{}, 0))) - assertar.Equal([]int{2, 4, 3, 1, 0}, WeightedPermutation(len(weightsArr), weightsArr, hashOf(hash.Hash{}, 1))) - assertar.Equal([]int{4, 2, 3, 1, 0}, WeightedPermutation(len(weightsArr), weightsArr, hashOf(hash.Hash{}, 2))) - assertar.Equal([]int{0, 2, 1, 3, 4}, WeightedPermutation(len(weightsArr), weightsArr, hashOf(hash.Hash{}, 3))) - assertar.Equal([]int{1, 2}, WeightedPermutation(len(weightsArr)/2, weightsArr, hashOf(hash.Hash{}, 4))) -} diff --git a/evm/go-x1/utils/wgmutex/wg_mutex.go b/evm/go-x1/utils/wgmutex/wg_mutex.go deleted file mode 100644 index 6c38989..0000000 --- a/evm/go-x1/utils/wgmutex/wg_mutex.go +++ /dev/null @@ -1,25 +0,0 @@ -package wgmutex - -import "sync" - -type WgMutex struct { - *sync.RWMutex - wg *sync.WaitGroup -} - -func New(m *sync.RWMutex, wg *sync.WaitGroup) *WgMutex { - return &WgMutex{ - RWMutex: m, - wg: wg, - } -} - -func (m *WgMutex) Lock() { - m.RWMutex.Lock() - m.wg.Wait() -} - -func (m *WgMutex) RLock() { - m.RWMutex.RLock() - m.wg.Wait() -} diff --git a/evm/go-x1/valkeystore/cache.go b/evm/go-x1/valkeystore/cache.go deleted file mode 100644 index b963dd2..0000000 --- a/evm/go-x1/valkeystore/cache.go +++ /dev/null @@ -1,68 +0,0 @@ -package valkeystore - -import ( - "errors" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/valkeystore/encryption" -) - -var ( - ErrAlreadyUnlocked = errors.New("already unlocked") - ErrLocked = errors.New("key is locked") -) - -type CachedKeystore struct { - backend RawKeystoreI - cache map[string]*encryption.PrivateKey -} - -func NewCachedKeystore(backend RawKeystoreI) *CachedKeystore { - return &CachedKeystore{ - backend: backend, - cache: make(map[string]*encryption.PrivateKey), - } -} - -func (c *CachedKeystore) Unlocked(pubkey validatorpk.PubKey) bool { - _, ok := c.cache[c.idxOf(pubkey)] - return ok -} - -func (c *CachedKeystore) Has(pubkey validatorpk.PubKey) bool { - if c.Unlocked(pubkey) { - return true - } - return c.backend.Has(pubkey) -} - -func (c *CachedKeystore) Unlock(pubkey validatorpk.PubKey, auth string) error { - if c.Unlocked(pubkey) { - return ErrAlreadyUnlocked - } - key, err := c.backend.Get(pubkey, auth) - if err != nil { - return err - } - c.cache[c.idxOf(pubkey)] = key - return nil -} - -func (c *CachedKeystore) GetUnlocked(pubkey validatorpk.PubKey) (*encryption.PrivateKey, error) { - if !c.Unlocked(pubkey) { - return nil, ErrLocked - } - return c.cache[c.idxOf(pubkey)], nil -} - -func (c *CachedKeystore) idxOf(pubkey validatorpk.PubKey) string { - return string(pubkey.Bytes()) -} - -func (c *CachedKeystore) Add(pubkey validatorpk.PubKey, key []byte, auth string) error { - return c.backend.Add(pubkey, key, auth) -} - -func (c *CachedKeystore) Get(pubkey validatorpk.PubKey, auth string) (*encryption.PrivateKey, error) { - return c.backend.Get(pubkey, auth) -} diff --git a/evm/go-x1/valkeystore/common_test.go b/evm/go-x1/valkeystore/common_test.go deleted file mode 100644 index a41add2..0000000 --- a/evm/go-x1/valkeystore/common_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package valkeystore - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" -) - -var ( - pubkey1, _ = validatorpk.FromString("0xc0045ea4ce3ab0748574f0290dadcb45545aff82d8baa72e5b4c84a19d2e1f16fb3dc487430b4189ded650a94148e57a60ca8cbf4da414dbfd3b072f0a5b9a746235") - key1 = common.FromHex("e77b3e0e1bfb52a1e22b73dd7941336443363c4942c5c70869302f66940eefc2") - name1 = "c0045ea4ce3ab0748574f0290dadcb45545aff82d8baa72e5b4c84a19d2e1f16fb3dc487430b4189ded650a94148e57a60ca8cbf4da414dbfd3b072f0a5b9a746235" - file1 = common.FromHex("7b2274797065223a3139322c227075626b6579223a2230343565613463653361623037343835373466303239306461646362343535343561666638326438626161373265356234633834613139643265316631366662336463343837343330623431383964656436353061393431343865353761363063613863626634646134313464626664336230373266306135623961373436323335222c2263727970746f223a7b22636970686572223a226165732d3132382d637472222c2263697068657274657874223a2262623662363638336636316633363231636131313530366137633666366661616130313761663833613861656163373139303666336332643664613265353132222c22636970686572706172616d73223a7b226976223a223963643333343332373230386164616666373162653936323434643339666263227d2c226b6466223a22736372797074222c226b6466706172616d73223a7b22646b6c656e223a33322c226e223a343039362c2270223a362c2272223a382c2273616c74223a2232383232656134316338366462366435353065333733326565333661343639393765656438326661366530646536383234343530373562356261396461633934227d2c226d6163223a2261623366363934396234306130366664326264396663386237316664643566353933386164333866616236366236396636663931393363373362336439613939227d7d") - pubkey2, _ = validatorpk.FromString("0xc00459b25a40ac4af6d114deb2f899bb371869b467955dd3106302309263c6c7786209306dae5564cbeb75805ff517bb49dce467f785c138837782a0c0becf4b122c") - key2 = common.FromHex("72c7c0305f3bb74720683aad5342b44bec96efed8256ed76bb3ba6421947f0a5") - name2 = "c00459b25a40ac4af6d114deb2f899bb371869b467955dd3106302309263c6c7786209306dae5564cbeb75805ff517bb49dce467f785c138837782a0c0becf4b122c" - file2 = common.FromHex("7b2274797065223a3139322c227075626b6579223a2230343539623235613430616334616636643131346465623266383939626233373138363962343637393535646433313036333032333039323633633663373738363230393330366461653535363463626562373538303566663531376262343964636534363766373835633133383833373738326130633062656366346231323263222c2263727970746f223a7b22636970686572223a226165732d3132382d637472222c2263697068657274657874223a2237373833373830643537633835373530366234646139636461643632316638653161346132386130376335636264343564653332663536313566323630396532222c22636970686572706172616d73223a7b226976223a226338346563613438333231346364393461353933663539336362633032616437227d2c226b6466223a22736372797074222c226b6466706172616d73223a7b22646b6c656e223a33322c226e223a343039362c2270223a362c2272223a382c2273616c74223a2265353061623135366138636430633537363431336331346563373162336637666465373466363362633161323631376233343465363933616136633733626237227d2c226d6163223a2231383535343832663266363837313236393931613233313665613061656535386636363932306637653366633330653038656133663832666430636162323232227d7d") -) - -func testGet(t *testing.T, keystore RawKeystoreI, expPubkey validatorpk.PubKey, expKey []byte, auth string) { - require := require.New(t) - - wrongPubkey := expPubkey - wrongPubkey.Type++ - key, err := keystore.Get(wrongPubkey, auth) - require.EqualError(err, ErrNotFound.Error()) - require.Nil(key) - - wrongPubkey = expPubkey - wrongPubkey.Raw = []byte{0} - key, err = keystore.Get(wrongPubkey, auth) - require.EqualError(err, ErrNotFound.Error()) - require.Nil(key) - - key, err = keystore.Get(expPubkey, auth) - require.NoError(err) - require.Equal(expPubkey.Type, key.Type) - require.Equal(expKey, key.Bytes) - - key, err = keystore.Get(expPubkey, auth+"1") - require.EqualError(err, "could not decrypt key with given password") - require.Nil(key) -} diff --git a/evm/go-x1/valkeystore/default.go b/evm/go-x1/valkeystore/default.go deleted file mode 100644 index 6799fac..0000000 --- a/evm/go-x1/valkeystore/default.go +++ /dev/null @@ -1,20 +0,0 @@ -package valkeystore - -import ( - "github.com/ethereum/go-ethereum/accounts/keystore" - - "github.com/Fantom-foundation/go-opera/valkeystore/encryption" -) - -func NewDefaultFileRawKeystore(dir string) *FileKeystore { - enc := encryption.New(keystore.StandardScryptN, keystore.StandardScryptP) - return NewFileKeystore(dir, enc) -} - -func NewDefaultMemKeystore() *SyncedKeystore { - return NewSyncedKeystore(NewCachedKeystore(NewMemKeystore())) -} - -func NewDefaultFileKeystore(dir string) *SyncedKeystore { - return NewSyncedKeystore(NewCachedKeystore(NewDefaultFileRawKeystore(dir))) -} diff --git a/evm/go-x1/valkeystore/encryption/encryption.go b/evm/go-x1/valkeystore/encryption/encryption.go deleted file mode 100644 index a4e53cf..0000000 --- a/evm/go-x1/valkeystore/encryption/encryption.go +++ /dev/null @@ -1,139 +0,0 @@ -package encryption - -import ( - "bytes" - "crypto/ecdsa" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "os" - - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" -) - -var ( - ErrNotSupportedType = errors.New("not supported key type") -) - -type PrivateKey struct { - Type uint8 - Bytes []byte - Decoded interface{} -} - -type EncryptedKeyJSON struct { - Type uint8 `json:"type"` - PublicKey string `json:"pubkey"` - Crypto keystore.CryptoJSON `json:"crypto"` -} - -type Keystore struct { - scryptN int - scryptP int -} - -func New(scryptN int, scryptP int) *Keystore { - return &Keystore{ - scryptN: scryptN, - scryptP: scryptP, - } -} - -func (ks Keystore) ReadKey(wantPubkey validatorpk.PubKey, filename, auth string) (*PrivateKey, error) { - // Load the key from the keystore and decrypt its contents - keyjson, err := ioutil.ReadFile(filename) - if err != nil { - return nil, err - } - key, err := DecryptKey(keyjson, auth) - if err != nil { - return nil, err - } - // Make sure we're really operating on the requested key (no swap attacks) - keySecp256k1 := key.Decoded.(*ecdsa.PrivateKey) - gotPubkey := crypto.FromECDSAPub(&keySecp256k1.PublicKey) - if bytes.Compare(wantPubkey.Raw, gotPubkey) != 0 { - return nil, fmt.Errorf("key content mismatch: have public key %X, want %X", gotPubkey, wantPubkey.Raw) - } - return key, nil -} - -func (ks Keystore) StoreKey(filename string, pubkey validatorpk.PubKey, key []byte, auth string) error { - keyjson, err := ks.EncryptKey(pubkey, key, auth) - if err != nil { - return err - } - // Write into temporary file - tmpName, err := writeTemporaryKeyFile(filename, keyjson) - if err != nil { - return err - } - return os.Rename(tmpName, filename) -} - -// EncryptKey encrypts a key using the specified scrypt parameters into a json -// blob that can be decrypted later on. -func (ks Keystore) EncryptKey(pubkey validatorpk.PubKey, key []byte, auth string) ([]byte, error) { - if pubkey.Type != validatorpk.Types.Secp256k1 { - return nil, ErrNotSupportedType - } - cryptoStruct, err := keystore.EncryptDataV3(key, []byte(auth), ks.scryptN, ks.scryptP) - if err != nil { - return nil, err - } - encryptedKeyJSON := EncryptedKeyJSON{ - Type: pubkey.Type, - PublicKey: common.Bytes2Hex(pubkey.Raw), - Crypto: cryptoStruct, - } - return json.Marshal(encryptedKeyJSON) -} - -// DecryptKey decrypts a key from a json blob, returning the private key itself. -func DecryptKey(keyjson []byte, auth string) (*PrivateKey, error) { - // Parse the json into a simple map to fetch the key version - m := make(map[string]interface{}) - if err := json.Unmarshal(keyjson, &m); err != nil { - return nil, err - } - var ( - keyBytes []byte - err error - ) - k := new(EncryptedKeyJSON) - if err := json.Unmarshal(keyjson, k); err != nil { - return nil, err - } - if k.Type != validatorpk.Types.Secp256k1 { - return nil, ErrNotSupportedType - } - keyBytes, err = decryptKey_secp256k1(k, auth) - // Handle any decryption errors and return the key - if err != nil { - return nil, err - } - - decoded, err := crypto.ToECDSA(keyBytes) - if err != nil { - return nil, err - } - - return &PrivateKey{ - Type: k.Type, - Bytes: keyBytes, - Decoded: decoded, - }, nil -} - -func decryptKey_secp256k1(keyProtected *EncryptedKeyJSON, auth string) (keyBytes []byte, err error) { - plainText, err := keystore.DecryptDataV3(keyProtected.Crypto, auth) - if err != nil { - return nil, err - } - return plainText, err -} diff --git a/evm/go-x1/valkeystore/encryption/io.go b/evm/go-x1/valkeystore/encryption/io.go deleted file mode 100644 index 5f800f9..0000000 --- a/evm/go-x1/valkeystore/encryption/io.go +++ /dev/null @@ -1,29 +0,0 @@ -package encryption - -import ( - "io/ioutil" - "os" - "path/filepath" -) - -func writeTemporaryKeyFile(file string, content []byte) (string, error) { - // Create the keystore directory with appropriate permissions - // in case it is not present yet. - const dirPerm = 0700 - if err := os.MkdirAll(filepath.Dir(file), dirPerm); err != nil { - return "", err - } - // Atomic write: create a temporary hidden file first - // then move it into place. TempFile assigns mode 0600. - f, err := ioutil.TempFile(filepath.Dir(file), "."+filepath.Base(file[0:16])+".tmp") - if err != nil { - return "", err - } - if _, err := f.Write(content); err != nil { - f.Close() - os.Remove(f.Name()) - return "", err - } - f.Close() - return f.Name(), nil -} diff --git a/evm/go-x1/valkeystore/encryption/migration.go b/evm/go-x1/valkeystore/encryption/migration.go deleted file mode 100644 index ab26db9..0000000 --- a/evm/go-x1/valkeystore/encryption/migration.go +++ /dev/null @@ -1,45 +0,0 @@ -package encryption - -import ( - "encoding/json" - "io/ioutil" - "os" - - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/common" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" -) - -type encryptedAccountKeyJSONV3 struct { - Address string `json:"address"` - Crypto keystore.CryptoJSON `json:"crypto"` - Id string `json:"id"` - Version int `json:"version"` -} - -func MigrateAccountToValidatorKey(acckeypath string, valkeypath string, pubkey validatorpk.PubKey) error { - acckeyjson, err := ioutil.ReadFile(acckeypath) - if err != nil { - return err - } - acck := new(encryptedAccountKeyJSONV3) - if err := json.Unmarshal(acckeyjson, acck); err != nil { - return err - } - - valk := EncryptedKeyJSON{ - Type: validatorpk.Types.Secp256k1, - PublicKey: common.Bytes2Hex(pubkey.Raw), - Crypto: acck.Crypto, - } - valkeyjson, err := json.Marshal(valk) - if err != nil { - return err - } - tmpName, err := writeTemporaryKeyFile(valkeypath, valkeyjson) - if err != nil { - return err - } - return os.Rename(tmpName, valkeypath) -} diff --git a/evm/go-x1/valkeystore/files.go b/evm/go-x1/valkeystore/files.go deleted file mode 100644 index 8fb8d88..0000000 --- a/evm/go-x1/valkeystore/files.go +++ /dev/null @@ -1,59 +0,0 @@ -package valkeystore - -import ( - "errors" - "os" - "path" - - "github.com/ethereum/go-ethereum/common" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/valkeystore/encryption" -) - -var ( - ErrNotFound = errors.New("key is not found") - ErrAlreadyExists = errors.New("key already exists") -) - -type FileKeystore struct { - enc *encryption.Keystore - dir string -} - -func NewFileKeystore(dir string, enc *encryption.Keystore) *FileKeystore { - return &FileKeystore{ - enc: enc, - dir: dir, - } -} - -func (f *FileKeystore) Has(pubkey validatorpk.PubKey) bool { - return fileExists(f.PathOf(pubkey)) -} - -func (f *FileKeystore) Add(pubkey validatorpk.PubKey, key []byte, auth string) error { - if f.Has(pubkey) { - return ErrAlreadyExists - } - return f.enc.StoreKey(f.PathOf(pubkey), pubkey, key, auth) -} - -func (f *FileKeystore) Get(pubkey validatorpk.PubKey, auth string) (*encryption.PrivateKey, error) { - if !f.Has(pubkey) { - return nil, ErrNotFound - } - return f.enc.ReadKey(pubkey, f.PathOf(pubkey), auth) -} - -func (f *FileKeystore) PathOf(pubkey validatorpk.PubKey) string { - return path.Join(f.dir, common.Bytes2Hex(pubkey.Bytes())) -} - -func fileExists(filename string) bool { - info, err := os.Stat(filename) - if err != nil { - return false - } - return !info.IsDir() -} diff --git a/evm/go-x1/valkeystore/files_test.go b/evm/go-x1/valkeystore/files_test.go deleted file mode 100644 index a00b8db..0000000 --- a/evm/go-x1/valkeystore/files_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package valkeystore - -import ( - "io/ioutil" - "os" - "path" - "testing" - - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/stretchr/testify/require" - - "github.com/Fantom-foundation/go-opera/valkeystore/encryption" -) - -func TestFileKeystoreAdd(t *testing.T) { - dir, err := ioutil.TempDir("", "valkeystore_test") - if err != nil { - return - } - defer os.RemoveAll(dir) - - require := require.New(t) - keystore := NewFileKeystore(dir, encryption.New(keystore.LightScryptN, keystore.LightScryptP)) - - key, err := keystore.Get(pubkey1, "auth1") - require.EqualError(err, ErrNotFound.Error()) - require.Nil(key) - - err = keystore.Add(pubkey1, key1, "auth1") - require.NoError(err) - _, err = os.Stat(path.Join(dir, name1)) - require.NoError(err) - - testGet(t, keystore, pubkey1, key1, "auth1") - - err = keystore.Add(pubkey2, key2, "auth2") - require.NoError(err) - _, err = os.Stat(path.Join(dir, name2)) - require.NoError(err) - - testGet(t, keystore, pubkey1, key1, "auth1") - testGet(t, keystore, pubkey2, key2, "auth2") - - err = keystore.Add(pubkey2, key2, "auth1") - require.Error(err, ErrAlreadyExists.Error()) - - testGet(t, keystore, pubkey2, key2, "auth2") -} - -func TestFileKeystoreRead(t *testing.T) { - dir, err := ioutil.TempDir("", "valkeystore_test") - if err != nil { - return - } - defer os.RemoveAll(dir) - - require := require.New(t) - keystore := NewFileKeystore(dir, encryption.New(keystore.LightScryptN, keystore.LightScryptP)) - - fd, err := os.Create(path.Join(dir, name1)) - require.NoError(err) - _, err = fd.Write(file1) - require.NoError(err) - - testGet(t, keystore, pubkey1, key1, "auth1") - - fd, err = os.Create(path.Join(dir, name2)) - require.NoError(err) - _, err = fd.Write(file2) - require.NoError(err) - - testGet(t, keystore, pubkey1, key1, "auth1") - testGet(t, keystore, pubkey2, key2, "auth2") -} diff --git a/evm/go-x1/valkeystore/keystore.go b/evm/go-x1/valkeystore/keystore.go deleted file mode 100644 index a28dbc2..0000000 --- a/evm/go-x1/valkeystore/keystore.go +++ /dev/null @@ -1,19 +0,0 @@ -package valkeystore - -import ( - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/valkeystore/encryption" -) - -type RawKeystoreI interface { - Has(pubkey validatorpk.PubKey) bool - Add(pubkey validatorpk.PubKey, key []byte, auth string) error - Get(pubkey validatorpk.PubKey, auth string) (*encryption.PrivateKey, error) -} - -type KeystoreI interface { - RawKeystoreI - Unlock(pubkey validatorpk.PubKey, auth string) error - Unlocked(pubkey validatorpk.PubKey) bool - GetUnlocked(pubkey validatorpk.PubKey) (*encryption.PrivateKey, error) -} diff --git a/evm/go-x1/valkeystore/mem.go b/evm/go-x1/valkeystore/mem.go deleted file mode 100644 index 4ad9042..0000000 --- a/evm/go-x1/valkeystore/mem.go +++ /dev/null @@ -1,61 +0,0 @@ -package valkeystore - -import ( - "errors" - - "github.com/ethereum/go-ethereum/crypto" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/valkeystore/encryption" -) - -type MemKeystore struct { - mem map[string]*encryption.PrivateKey - auth map[string]string -} - -func NewMemKeystore() *MemKeystore { - return &MemKeystore{ - mem: make(map[string]*encryption.PrivateKey), - auth: make(map[string]string), - } -} - -func (m *MemKeystore) Has(pubkey validatorpk.PubKey) bool { - _, ok := m.mem[m.idxOf(pubkey)] - return ok -} - -func (m *MemKeystore) Add(pubkey validatorpk.PubKey, key []byte, auth string) error { - if m.Has(pubkey) { - return ErrAlreadyExists - } - if pubkey.Type != validatorpk.Types.Secp256k1 { - return encryption.ErrNotSupportedType - } - decoded, err := crypto.ToECDSA(key) - if err != nil { - return err - } - m.mem[m.idxOf(pubkey)] = &encryption.PrivateKey{ - Type: pubkey.Type, - Bytes: key, - Decoded: decoded, - } - m.auth[m.idxOf(pubkey)] = auth - return nil -} - -func (m *MemKeystore) Get(pubkey validatorpk.PubKey, auth string) (*encryption.PrivateKey, error) { - if !m.Has(pubkey) { - return nil, ErrNotFound - } - if m.auth[m.idxOf(pubkey)] != auth { - return nil, errors.New("could not decrypt key with given password") - } - return m.mem[m.idxOf(pubkey)], nil -} - -func (m *MemKeystore) idxOf(pubkey validatorpk.PubKey) string { - return string(pubkey.Bytes()) -} diff --git a/evm/go-x1/valkeystore/mem_test.go b/evm/go-x1/valkeystore/mem_test.go deleted file mode 100644 index b20a28e..0000000 --- a/evm/go-x1/valkeystore/mem_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package valkeystore - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestMemKeystoreAdd(t *testing.T) { - require := require.New(t) - keystore := NewMemKeystore() - - key, err := keystore.Get(pubkey1, "auth1") - require.EqualError(err, ErrNotFound.Error()) - require.Nil(key) - - err = keystore.Add(pubkey1, key1, "auth1") - require.NoError(err) - - testGet(t, keystore, pubkey1, key1, "auth1") - - err = keystore.Add(pubkey2, key2, "auth2") - require.NoError(err) - - testGet(t, keystore, pubkey1, key1, "auth1") - testGet(t, keystore, pubkey2, key2, "auth2") - - err = keystore.Add(pubkey2, key2, "auth1") - require.Error(err, ErrAlreadyExists.Error()) - - testGet(t, keystore, pubkey2, key2, "auth2") -} diff --git a/evm/go-x1/valkeystore/signer.go b/evm/go-x1/valkeystore/signer.go deleted file mode 100644 index 4e8aa9d..0000000 --- a/evm/go-x1/valkeystore/signer.go +++ /dev/null @@ -1,43 +0,0 @@ -package valkeystore - -import ( - "crypto/ecdsa" - - "github.com/ethereum/go-ethereum/crypto" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/valkeystore/encryption" -) - -type SignerI interface { - Sign(pubkey validatorpk.PubKey, digest []byte) ([]byte, error) -} - -type Signer struct { - backend KeystoreI -} - -func NewSigner(backend KeystoreI) *Signer { - return &Signer{ - backend: backend, - } -} - -func (s *Signer) Sign(pubkey validatorpk.PubKey, digest []byte) ([]byte, error) { - if pubkey.Type != validatorpk.Types.Secp256k1 { - return nil, encryption.ErrNotSupportedType - } - key, err := s.backend.GetUnlocked(pubkey) - if err != nil { - return nil, err - } - - secp256k1Key := key.Decoded.(*ecdsa.PrivateKey) - - sigRSV, err := crypto.Sign(digest, secp256k1Key) - if err != nil { - return nil, err - } - sigRS := sigRSV[:64] - return sigRS, err -} diff --git a/evm/go-x1/valkeystore/sync.go b/evm/go-x1/valkeystore/sync.go deleted file mode 100644 index 61adcb9..0000000 --- a/evm/go-x1/valkeystore/sync.go +++ /dev/null @@ -1,55 +0,0 @@ -package valkeystore - -import ( - "sync" - - "github.com/Fantom-foundation/go-opera/inter/validatorpk" - "github.com/Fantom-foundation/go-opera/valkeystore/encryption" -) - -type SyncedKeystore struct { - backend KeystoreI - mu sync.Mutex -} - -func NewSyncedKeystore(backend KeystoreI) *SyncedKeystore { - return &SyncedKeystore{ - backend: backend, - } -} - -func (s *SyncedKeystore) Unlocked(pubkey validatorpk.PubKey) bool { - s.mu.Lock() - defer s.mu.Unlock() - return s.backend.Unlocked(pubkey) -} - -func (s *SyncedKeystore) Has(pubkey validatorpk.PubKey) bool { - s.mu.Lock() - defer s.mu.Unlock() - return s.backend.Has(pubkey) -} - -func (s *SyncedKeystore) Unlock(pubkey validatorpk.PubKey, auth string) error { - s.mu.Lock() - defer s.mu.Unlock() - return s.backend.Unlock(pubkey, auth) -} - -func (s *SyncedKeystore) GetUnlocked(pubkey validatorpk.PubKey) (*encryption.PrivateKey, error) { - s.mu.Lock() - defer s.mu.Unlock() - return s.backend.GetUnlocked(pubkey) -} - -func (s *SyncedKeystore) Add(pubkey validatorpk.PubKey, key []byte, auth string) error { - s.mu.Lock() - defer s.mu.Unlock() - return s.backend.Add(pubkey, key, auth) -} - -func (s *SyncedKeystore) Get(pubkey validatorpk.PubKey, auth string) (*encryption.PrivateKey, error) { - s.mu.Lock() - defer s.mu.Unlock() - return s.backend.Get(pubkey, auth) -} diff --git a/evm/go-x1/vecmt/index.go b/evm/go-x1/vecmt/index.go deleted file mode 100644 index a2699ee..0000000 --- a/evm/go-x1/vecmt/index.go +++ /dev/null @@ -1,155 +0,0 @@ -package vecmt - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/kvdb" - "github.com/Fantom-foundation/lachesis-base/kvdb/table" - "github.com/Fantom-foundation/lachesis-base/utils/cachescale" - "github.com/Fantom-foundation/lachesis-base/utils/wlru" - "github.com/Fantom-foundation/lachesis-base/vecengine" - "github.com/Fantom-foundation/lachesis-base/vecengine/vecflushable" - "github.com/Fantom-foundation/lachesis-base/vecfc" - "github.com/syndtr/goleveldb/leveldb/opt" -) - -// IndexCacheConfig - config for cache sizes of Engine -type IndexCacheConfig struct { - HighestBeforeTimeSize uint - DBCache int -} - -// IndexConfig - Engine config (cache sizes) -type IndexConfig struct { - Fc vecfc.IndexConfig - Caches IndexCacheConfig -} - -// Index is a data to detect forkless-cause condition, calculate median timestamp, detect forks. -type Index struct { - *vecfc.Index - Base *vecfc.Index - baseCallbacks vecengine.Callbacks - - crit func(error) - validators *pos.Validators - validatorIdxs map[idx.ValidatorID]idx.Validator - - getEvent func(hash.Event) dag.Event - - vecDb kvdb.Store - table struct { - HighestBeforeTime kvdb.Store `table:"T"` - } - - cache struct { - HighestBeforeTime *wlru.Cache - } - - cfg IndexConfig -} - -// DefaultConfig returns default index config -func DefaultConfig(scale cachescale.Func) IndexConfig { - return IndexConfig{ - Fc: vecfc.DefaultConfig(scale), - Caches: IndexCacheConfig{ - HighestBeforeTimeSize: scale.U(160 * 1024), - DBCache: scale.I(10 * opt.MiB), - }, - } -} - -// LiteConfig returns default index config for tests -func LiteConfig() IndexConfig { - return IndexConfig{ - Fc: vecfc.LiteConfig(), - Caches: IndexCacheConfig{ - HighestBeforeTimeSize: 4 * 1024, - }, - } -} - -// NewIndex creates Index instance. -func NewIndex(crit func(error), config IndexConfig) *Index { - vi := &Index{ - cfg: config, - crit: crit, - } - engine := vecengine.NewIndex(crit, vi.GetEngineCallbacks()) - - vi.Base = vecfc.NewIndexWithEngine(crit, config.Fc, engine) - vi.Index = vi.Base - vi.baseCallbacks = vi.Base.GetEngineCallbacks() - vi.initCaches() - - return vi -} - -func NewIndexWithBase(crit func(error), config IndexConfig, base *vecfc.Index) *Index { - vi := &Index{ - Index: base, - Base: base, - baseCallbacks: base.GetEngineCallbacks(), - cfg: config, - crit: crit, - } - vi.initCaches() - - return vi -} - -func (vi *Index) initCaches() { - vi.cache.HighestBeforeTime, _ = wlru.New(vi.cfg.Caches.HighestBeforeTimeSize, int(vi.cfg.Caches.HighestBeforeTimeSize)) -} - -// Reset resets buffers. -func (vi *Index) Reset(validators *pos.Validators, db kvdb.Store, getEvent func(hash.Event) dag.Event) { - fdb := vecflushable.Wrap(db, vi.cfg.Caches.DBCache) - vi.vecDb = fdb - vi.Base.Reset(validators, fdb, getEvent) - vi.getEvent = getEvent - vi.validators = validators - vi.validatorIdxs = validators.Idxs() - vi.onDropNotFlushed() - - table.MigrateTables(&vi.table, vi.vecDb) -} - -func (vi *Index) GetEngineCallbacks() vecengine.Callbacks { - return vecengine.Callbacks{ - GetHighestBefore: func(event hash.Event) vecengine.HighestBeforeI { - return vi.GetHighestBefore(event) - }, - GetLowestAfter: func(event hash.Event) vecengine.LowestAfterI { - return vi.baseCallbacks.GetLowestAfter(event) - }, - SetHighestBefore: func(event hash.Event, b vecengine.HighestBeforeI) { - vi.SetHighestBefore(event, b.(*HighestBefore)) - }, - SetLowestAfter: func(event hash.Event, i vecengine.LowestAfterI) { - vi.baseCallbacks.SetLowestAfter(event, i) - }, - NewHighestBefore: func(size idx.Validator) vecengine.HighestBeforeI { - return NewHighestBefore(size) - }, - NewLowestAfter: func(size idx.Validator) vecengine.LowestAfterI { - return vi.baseCallbacks.NewLowestAfter(size) - }, - OnDropNotFlushed: func() { - vi.baseCallbacks.OnDropNotFlushed() - vi.onDropNotFlushed() - }, - } -} - -func (vi *Index) onDropNotFlushed() { - vi.cache.HighestBeforeTime.Purge() -} - -// GetMergedHighestBefore returns HighestBefore vector clock without branches, where branches are merged into one -func (vi *Index) GetMergedHighestBefore(id hash.Event) *HighestBefore { - return vi.Engine.GetMergedHighestBefore(id).(*HighestBefore) -} diff --git a/evm/go-x1/vecmt/index_test.go b/evm/go-x1/vecmt/index_test.go deleted file mode 100644 index 4ca0419..0000000 --- a/evm/go-x1/vecmt/index_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package vecmt - -import ( - "testing" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/dag/tdag" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" - - "github.com/Fantom-foundation/go-opera/inter" -) - -var ( - testASCIIScheme = ` -a1.0 b1.0 c1.0 d1.0 e1.0 -║ ║ ║ ║ ║ -║ ╠──────╫───── d2.0 ║ -║ ║ ║ ║ ║ -║ b2.1 ──╫──────╣ e2.1 -║ ║ ║ ║ ║ -║ ╠──────╫───── d3.1 ║ -a2.1 ──╣ ║ ║ ║ -║ ║ ║ ║ ║ -║ b3.2 ──╣ ║ ║ -║ ║ ║ ║ ║ -║ ╠──────╫───── d4.2 ║ -║ ║ ║ ║ ║ -║ ╠───── c2.2 ║ e3.2 -║ ║ ║ ║ ║ -` -) - -type eventWithCreationTime struct { - dag.Event - creationTime inter.Timestamp -} - -func (e *eventWithCreationTime) CreationTime() inter.Timestamp { - return e.creationTime -} - -func BenchmarkIndex_Add(b *testing.B) { - b.StopTimer() - ordered := make(dag.Events, 0) - nodes, _, _ := tdag.ASCIIschemeForEach(testASCIIScheme, tdag.ForEachEvent{ - Process: func(e dag.Event, name string) { - ordered = append(ordered, e) - }, - }) - validatorsBuilder := pos.NewBuilder() - for _, peer := range nodes { - validatorsBuilder.Set(peer, 1) - } - validators := validatorsBuilder.Build() - events := make(map[hash.Event]dag.Event) - getEvent := func(id hash.Event) dag.Event { - return events[id] - } - for _, e := range ordered { - events[e.ID()] = e - } - - vecClock := NewIndex(func(err error) { panic(err) }, LiteConfig()) - vecClock.Reset(validators, memorydb.New(), getEvent) - - for i := 0; i < b.N; i++ { - b.StopTimer() - vecClock.Reset(validators, memorydb.New(), getEvent) - b.StartTimer() - for _, e := range ordered { - err := vecClock.Add(&eventWithCreationTime{e, inter.Timestamp(e.Seq())}) - if err != nil { - panic(err) - } - i++ - if i >= b.N { - break - } - } - } -} diff --git a/evm/go-x1/vecmt/median_time.go b/evm/go-x1/vecmt/median_time.go deleted file mode 100644 index 9fe00e6..0000000 --- a/evm/go-x1/vecmt/median_time.go +++ /dev/null @@ -1,84 +0,0 @@ -package vecmt - -import ( - "fmt" - "sort" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - - "github.com/Fantom-foundation/go-opera/inter" -) - -// medianTimeIndex is a handy index for the MedianTime() func -type medianTimeIndex struct { - weight pos.Weight - creationTime inter.Timestamp -} - -// MedianTime calculates weighted median of claimed time within highest observed events. -func (vi *Index) MedianTime(id hash.Event, defaultTime inter.Timestamp) inter.Timestamp { - vi.Engine.InitBranchesInfo() - // Get event by hash - _before := vi.Engine.GetMergedHighestBefore(id) - if _before == nil { - vi.crit(fmt.Errorf("event=%s not found", id.String())) - } - before := _before.(*HighestBefore) - - honestTotalWeight := pos.Weight(0) // isn't equal to validators.TotalWeight(), because doesn't count cheaters - highests := make([]medianTimeIndex, 0, len(vi.validatorIdxs)) - // convert []HighestBefore -> []medianTimeIndex - for creatorIdxI := range vi.validators.IDs() { - creatorIdx := idx.Validator(creatorIdxI) - highest := medianTimeIndex{} - highest.weight = vi.validators.GetWeightByIdx(creatorIdx) - highest.creationTime = before.VTime.Get(creatorIdx) - seq := before.VSeq.Get(creatorIdx) - - // edge cases - if seq.IsForkDetected() { - // cheaters don't influence medianTime - highest.weight = 0 - } else if seq.Seq == 0 { - // if no event was observed from this node, then use genesisTime - highest.creationTime = defaultTime - } - - highests = append(highests, highest) - honestTotalWeight += highest.weight - } - // it's technically possible honestTotalWeight == 0 (all validators are cheaters) - - // sort by claimed time (partial order is enough here, because we need only creationTime) - sort.Slice(highests, func(i, j int) bool { - a, b := highests[i], highests[j] - return a.creationTime < b.creationTime - }) - - // Calculate weighted median - halfWeight := honestTotalWeight / 2 - var currWeight pos.Weight - var median inter.Timestamp - for _, highest := range highests { - currWeight += highest.weight - if currWeight >= halfWeight { - median = highest.creationTime - break - } - } - - // sanity check - if currWeight < halfWeight || currWeight > honestTotalWeight { - vi.crit(fmt.Errorf("median wasn't calculated correctly, median=%d, currWeight=%d, totalWeight=%d, len(highests)=%d, id=%s", - median, - currWeight, - honestTotalWeight, - len(highests), - id.String(), - )) - } - - return median -} diff --git a/evm/go-x1/vecmt/median_time_test.go b/evm/go-x1/vecmt/median_time_test.go deleted file mode 100644 index c0fa148..0000000 --- a/evm/go-x1/vecmt/median_time_test.go +++ /dev/null @@ -1,192 +0,0 @@ -package vecmt - -import ( - "testing" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/vecfc" - "github.com/stretchr/testify/assert" - - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/dag/tdag" - "github.com/Fantom-foundation/lachesis-base/inter/pos" - "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" - - "github.com/Fantom-foundation/go-opera/inter" -) - -func TestMedianTimeOnIndex(t *testing.T) { - nodes := tdag.GenNodes(5) - weights := []pos.Weight{5, 4, 3, 2, 1} - validators := pos.ArrayToValidators(nodes, weights) - - vi := NewIndex(func(err error) { panic(err) }, LiteConfig()) - vi.Reset(validators, memorydb.New(), nil) - - assertar := assert.New(t) - { // seq=0 - e := hash.ZeroEvent - // validator indexes are sorted by weight amount - before := NewHighestBefore(idx.Validator(validators.Len())) - - before.VSeq.Set(0, vecfc.BranchSeq{Seq: 0}) - before.VTime.Set(0, 100) - - before.VSeq.Set(1, vecfc.BranchSeq{Seq: 0}) - before.VTime.Set(1, 100) - - before.VSeq.Set(2, vecfc.BranchSeq{Seq: 1}) - before.VTime.Set(2, 10) - - before.VSeq.Set(3, vecfc.BranchSeq{Seq: 1}) - before.VTime.Set(3, 10) - - before.VSeq.Set(4, vecfc.BranchSeq{Seq: 1}) - before.VTime.Set(4, 10) - - vi.SetHighestBefore(e, before) - assertar.Equal(inter.Timestamp(1), vi.MedianTime(e, 1)) - } - - { // fork seen = true - e := hash.ZeroEvent - // validator indexes are sorted by weight amount - before := NewHighestBefore(idx.Validator(validators.Len())) - - before.SetForkDetected(0) - before.VTime.Set(0, 100) - - before.SetForkDetected(1) - before.VTime.Set(1, 100) - - before.VSeq.Set(2, vecfc.BranchSeq{Seq: 1}) - before.VTime.Set(2, 10) - - before.VSeq.Set(3, vecfc.BranchSeq{Seq: 1}) - before.VTime.Set(3, 10) - - before.VSeq.Set(4, vecfc.BranchSeq{Seq: 1}) - before.VTime.Set(4, 10) - - vi.SetHighestBefore(e, before) - assertar.Equal(inter.Timestamp(10), vi.MedianTime(e, 1)) - } - - { // normal - e := hash.ZeroEvent - // validator indexes are sorted by weight amount - before := NewHighestBefore(idx.Validator(validators.Len())) - - before.VSeq.Set(0, vecfc.BranchSeq{Seq: 1}) - before.VTime.Set(0, 11) - - before.VSeq.Set(1, vecfc.BranchSeq{Seq: 2}) - before.VTime.Set(1, 12) - - before.VSeq.Set(2, vecfc.BranchSeq{Seq: 2}) - before.VTime.Set(2, 13) - - before.VSeq.Set(3, vecfc.BranchSeq{Seq: 3}) - before.VTime.Set(3, 14) - - before.VSeq.Set(4, vecfc.BranchSeq{Seq: 4}) - before.VTime.Set(4, 15) - - vi.SetHighestBefore(e, before) - assertar.Equal(inter.Timestamp(12), vi.MedianTime(e, 1)) - } - -} - -func TestMedianTimeOnDAG(t *testing.T) { - dagAscii := ` - ║ - nodeA001 - ║ - nodeA012 - ║ ║ - ║ nodeB001 - ║ ║ ║ - ║ ╠═══════════ nodeC001 - ║║ ║ ║ ║ - ║╚══════════─╫─══════════─╫─══════════ nodeD001 -║║ ║ ║ ║ -╚ nodeA002════╬════════════╬════════════╣ - ║║ ║ ║ ║ - ║╚══════════─╫─══════════─╫─══════════ nodeD002 - ║ ║ ║ ║ - nodeA003════─╫─══════════─╫─═══════════╣ - ║ ║ ║ - ╠════════════nodeB002 ║ - ║ ║ ║ - ╠════════════╫═══════════ nodeC002 -` - - weights := []pos.Weight{3, 4, 2, 1} - genesisTime := inter.Timestamp(1) - creationTimes := map[string]inter.Timestamp{ - "nodeA001": inter.Timestamp(111), - "nodeB001": inter.Timestamp(112), - "nodeC001": inter.Timestamp(13), - "nodeD001": inter.Timestamp(14), - "nodeA002": inter.Timestamp(120), - "nodeD002": inter.Timestamp(20), - "nodeA012": inter.Timestamp(120), - "nodeA003": inter.Timestamp(20), - "nodeB002": inter.Timestamp(20), - "nodeC002": inter.Timestamp(35), - } - medianTimes := map[string]inter.Timestamp{ - "nodeA001": genesisTime, - "nodeB001": genesisTime, - "nodeC001": inter.Timestamp(13), - "nodeD001": genesisTime, - "nodeA002": inter.Timestamp(112), - "nodeD002": genesisTime, - "nodeA012": genesisTime, - "nodeA003": inter.Timestamp(20), - "nodeB002": inter.Timestamp(20), - "nodeC002": inter.Timestamp(35), - } - t.Run("testMedianTimeOnDAG", func(t *testing.T) { - testMedianTime(t, dagAscii, weights, creationTimes, medianTimes, genesisTime) - }) -} - -func testMedianTime(t *testing.T, dagAscii string, weights []pos.Weight, creationTimes map[string]inter.Timestamp, medianTimes map[string]inter.Timestamp, genesis inter.Timestamp) { - assertar := assert.New(t) - - var ordered dag.Events - nodes, _, named := tdag.ASCIIschemeForEach(dagAscii, tdag.ForEachEvent{ - Process: func(e dag.Event, name string) { - ordered = append(ordered, &eventWithCreationTime{e, creationTimes[name]}) - }, - }) - - validators := pos.ArrayToValidators(nodes, weights) - - events := make(map[hash.Event]dag.Event) - getEvent := func(id hash.Event) dag.Event { - return events[id] - } - - vi := NewIndex(func(err error) { panic(err) }, LiteConfig()) - vi.Reset(validators, memorydb.New(), getEvent) - - // push - for _, e := range ordered { - events[e.ID()] = e - assertar.NoError(vi.Add(e)) - vi.Flush() - } - - // check - for name, e := range named { - expected, ok := medianTimes[name] - if !ok { - continue - } - assertar.Equal(expected, vi.MedianTime(e.ID(), genesis), name) - } -} diff --git a/evm/go-x1/vecmt/no_cheaters.go b/evm/go-x1/vecmt/no_cheaters.go deleted file mode 100644 index 60770d2..0000000 --- a/evm/go-x1/vecmt/no_cheaters.go +++ /dev/null @@ -1,34 +0,0 @@ -package vecmt - -import ( - "errors" - - "github.com/Fantom-foundation/lachesis-base/hash" -) - -// NoCheaters excludes events which are observed by selfParents as cheaters. -// Called by emitter to exclude cheater's events from potential parents list. -func (vi *Index) NoCheaters(selfParent *hash.Event, options hash.Events) hash.Events { - if selfParent == nil { - return options - } - vi.InitBranchesInfo() - - if !vi.Engine.AtLeastOneFork() { - return options - } - - // no need to merge, because every branch is marked by IsForkDetected if fork is observed - highest := vi.Base.GetHighestBefore(*selfParent) - filtered := make(hash.Events, 0, len(options)) - for _, id := range options { - e := vi.getEvent(id) - if e == nil { - vi.crit(errors.New("event not found")) - } - if !highest.Get(vi.validatorIdxs[e.Creator()]).IsForkDetected() { - filtered.Add(id) - } - } - return filtered -} diff --git a/evm/go-x1/vecmt/store_vectors.go b/evm/go-x1/vecmt/store_vectors.go deleted file mode 100644 index 8854f8d..0000000 --- a/evm/go-x1/vecmt/store_vectors.go +++ /dev/null @@ -1,58 +0,0 @@ -package vecmt - -import ( - "github.com/Fantom-foundation/lachesis-base/hash" - "github.com/Fantom-foundation/lachesis-base/kvdb" -) - -func (vi *Index) getBytes(table kvdb.Store, id hash.Event) []byte { - key := id.Bytes() - b, err := table.Get(key) - if err != nil { - vi.crit(err) - } - return b -} - -func (vi *Index) setBytes(table kvdb.Store, id hash.Event, b []byte) { - key := id.Bytes() - err := table.Put(key, b) - if err != nil { - vi.crit(err) - } -} - -// GetHighestBeforeTime reads the vector from DB -func (vi *Index) GetHighestBeforeTime(id hash.Event) *HighestBeforeTime { - if bVal, okGet := vi.cache.HighestBeforeTime.Get(id); okGet { - return bVal.(*HighestBeforeTime) - } - - b := HighestBeforeTime(vi.getBytes(vi.table.HighestBeforeTime, id)) - if b == nil { - return nil - } - vi.cache.HighestBeforeTime.Add(id, &b, uint(len(b))) - return &b -} - -// GetHighestBefore reads the vector from DB -func (vi *Index) GetHighestBefore(id hash.Event) *HighestBefore { - return &HighestBefore{ - VSeq: vi.Base.GetHighestBefore(id), - VTime: vi.GetHighestBeforeTime(id), - } -} - -// SetHighestBeforeTime stores the vector into DB -func (vi *Index) SetHighestBeforeTime(id hash.Event, vec *HighestBeforeTime) { - vi.setBytes(vi.table.HighestBeforeTime, id, *vec) - - vi.cache.HighestBeforeTime.Add(id, vec, uint(len(*vec))) -} - -// SetHighestBefore stores the vectors into DB -func (vi *Index) SetHighestBefore(id hash.Event, vec *HighestBefore) { - vi.Base.SetHighestBefore(id, vec.VSeq) - vi.SetHighestBeforeTime(id, vec.VTime) -} diff --git a/evm/go-x1/vecmt/vector.go b/evm/go-x1/vecmt/vector.go deleted file mode 100644 index 1252904..0000000 --- a/evm/go-x1/vecmt/vector.go +++ /dev/null @@ -1,60 +0,0 @@ -package vecmt - -import ( - "encoding/binary" - - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/vecfc" - - "github.com/Fantom-foundation/go-opera/inter" -) - -/* - * Use binary form for optimization, to avoid serialization. As a result, DB cache works as elements cache. - */ - -type ( - // HighestBeforeTime is a vector of highest events (their CreationTime) which are observed by source event - HighestBeforeTime []byte - - HighestBefore struct { - VSeq *vecfc.HighestBeforeSeq - VTime *HighestBeforeTime - } -) - -// NewHighestBefore creates new HighestBefore vector. -func NewHighestBefore(size idx.Validator) *HighestBefore { - return &HighestBefore{ - VSeq: vecfc.NewHighestBeforeSeq(size), - VTime: NewHighestBeforeTime(size), - } -} - -// NewHighestBeforeTime creates new HighestBeforeTime vector. -func NewHighestBeforeTime(size idx.Validator) *HighestBeforeTime { - b := make(HighestBeforeTime, size*8) - return &b -} - -// Get i's position in the byte-encoded vector clock -func (b HighestBeforeTime) Get(i idx.Validator) inter.Timestamp { - for i >= b.Size() { - return 0 - } - return inter.Timestamp(binary.LittleEndian.Uint64(b[i*8 : (i+1)*8])) -} - -// Set i's position in the byte-encoded vector clock -func (b *HighestBeforeTime) Set(i idx.Validator, time inter.Timestamp) { - for i >= b.Size() { - // append zeros if exceeds size - *b = append(*b, []byte{0, 0, 0, 0, 0, 0, 0, 0}...) - } - binary.LittleEndian.PutUint64((*b)[i*8:(i+1)*8], uint64(time)) -} - -// Size of the vector clock -func (b HighestBeforeTime) Size() idx.Validator { - return idx.Validator(len(b) / 8) -} diff --git a/evm/go-x1/vecmt/vector_ops.go b/evm/go-x1/vecmt/vector_ops.go deleted file mode 100644 index 3af451c..0000000 --- a/evm/go-x1/vecmt/vector_ops.go +++ /dev/null @@ -1,93 +0,0 @@ -package vecmt - -import ( - "github.com/Fantom-foundation/lachesis-base/inter/dag" - "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/Fantom-foundation/lachesis-base/vecengine" - "github.com/Fantom-foundation/lachesis-base/vecfc" - - "github.com/Fantom-foundation/go-opera/inter" -) - -type CreationTimer interface { - CreationTime() inter.Timestamp -} - -func (b *HighestBefore) InitWithEvent(i idx.Validator, e dag.Event) { - b.VSeq.InitWithEvent(i, e) - b.VTime.Set(i, e.(CreationTimer).CreationTime()) -} - -func (b *HighestBefore) IsEmpty(i idx.Validator) bool { - return b.VSeq.IsEmpty(i) -} - -func (b *HighestBefore) IsForkDetected(i idx.Validator) bool { - return b.VSeq.IsForkDetected(i) -} - -func (b *HighestBefore) Seq(i idx.Validator) idx.Event { - return b.VSeq.Seq(i) -} - -func (b *HighestBefore) MinSeq(i idx.Validator) idx.Event { - return b.VSeq.MinSeq(i) -} - -func (b *HighestBefore) SetForkDetected(i idx.Validator) { - b.VSeq.SetForkDetected(i) -} - -func (self *HighestBefore) CollectFrom(_other vecengine.HighestBeforeI, num idx.Validator) { - other := _other.(*HighestBefore) - for branchID := idx.Validator(0); branchID < num; branchID++ { - hisSeq := other.VSeq.Get(branchID) - if hisSeq.Seq == 0 && !hisSeq.IsForkDetected() { - // hisSeq doesn't observe anything about this branchID - continue - } - mySeq := self.VSeq.Get(branchID) - - if mySeq.IsForkDetected() { - // mySeq observes the maximum already - continue - } - if hisSeq.IsForkDetected() { - // set fork detected - self.SetForkDetected(branchID) - } else { - if mySeq.Seq == 0 || mySeq.MinSeq > hisSeq.MinSeq { - // take hisSeq.MinSeq - mySeq.MinSeq = hisSeq.MinSeq - self.VSeq.Set(branchID, mySeq) - } - if mySeq.Seq < hisSeq.Seq { - // take hisSeq.Seq - mySeq.Seq = hisSeq.Seq - self.VSeq.Set(branchID, mySeq) - self.VTime.Set(branchID, other.VTime.Get(branchID)) - } - } - } -} - -func (self *HighestBefore) GatherFrom(to idx.Validator, _other vecengine.HighestBeforeI, from []idx.Validator) { - other := _other.(*HighestBefore) - // read all branches to find highest event - highestBranchSeq := vecfc.BranchSeq{} - highestBranchTime := inter.Timestamp(0) - for _, branchID := range from { - vseq := other.VSeq.Get(branchID) - vtime := other.VTime.Get(branchID) - if vseq.IsForkDetected() { - highestBranchSeq = vseq - break - } - if vseq.Seq > highestBranchSeq.Seq { - highestBranchSeq = vseq - highestBranchTime = vtime - } - } - self.VSeq.Set(to, highestBranchSeq) - self.VTime.Set(to, highestBranchTime) -} diff --git a/evm/go-x1/version/version.go b/evm/go-x1/version/version.go deleted file mode 100644 index ab58a31..0000000 --- a/evm/go-x1/version/version.go +++ /dev/null @@ -1,46 +0,0 @@ -package version - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/params" -) - -func init() { - params.VersionMajor = 1 // Major version component of the current release - params.VersionMinor = 1 // Minor version component of the current release - params.VersionPatch = 3 // Patch version component of the current release - params.VersionMeta = "rc.5" // Version metadata to append to the version string -} - -func BigToString(b *big.Int) string { - if len(b.Bytes()) > 8 { - return "_malformed_version_" - } - return U64ToString(b.Uint64()) -} - -func AsString() string { - return ToString(uint16(params.VersionMajor), uint16(params.VersionMinor), uint16(params.VersionPatch)) -} - -func AsU64() uint64 { - return ToU64(uint16(params.VersionMajor), uint16(params.VersionMinor), uint16(params.VersionPatch)) -} - -func AsBigInt() *big.Int { - return new(big.Int).SetUint64(AsU64()) -} - -func ToU64(vMajor, vMinor, vPatch uint16) uint64 { - return uint64(vMajor)*1e12 + uint64(vMinor)*1e6 + uint64(vPatch) -} - -func ToString(major, minor, patch uint16) string { - return fmt.Sprintf("%d.%d.%d", major, minor, patch) -} - -func U64ToString(v uint64) string { - return ToString(uint16((v/1e12)%1e6), uint16((v/1e6)%1e6), uint16(v%1e6)) -} diff --git a/evm/go-x1/version/version_test.go b/evm/go-x1/version/version_test.go deleted file mode 100644 index b1dd823..0000000 --- a/evm/go-x1/version/version_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package version - -import ( - "math" - "testing" - - "github.com/stretchr/testify/require" -) - -type testcase struct { - vMajor, vMinor, vPatch uint16 - result uint64 - str string -} - -func TestAsBigInt(t *testing.T) { - require := require.New(t) - - prev := testcase{0, 0, 0, 0, "0.0.0"} - for _, next := range []testcase{ - {0, 0, 1, 1, "0.0.1"}, - {0, 0, 2, 2, "0.0.2"}, - {0, 1, 0, 1000000, "0.1.0"}, - {0, 1, math.MaxUint16, 1065535, "0.1.65535"}, - {1, 0, 0, 1000000000000, "1.0.0"}, - {1, 0, math.MaxUint16, 1000000065535, "1.0.65535"}, - {1, 1, 0, 1000001000000, "1.1.0"}, - {2, 9, 9, 2000009000009, "2.9.9"}, - {3, 1, 0, 3000001000000, "3.1.0"}, - {math.MaxUint16, math.MaxUint16, math.MaxUint16, 65535065535065535, "65535.65535.65535"}, - } { - a := ToU64(prev.vMajor, prev.vMinor, prev.vPatch) - b := ToU64(next.vMajor, next.vMinor, next.vPatch) - require.Equal(a, prev.result) - require.Equal(b, next.result) - require.Equal(U64ToString(a), prev.str) - require.Equal(U64ToString(b), next.str) - require.Greater(b, a) - prev = next - } -} diff --git a/go-x1 b/go-x1 deleted file mode 160000 index 83dba45..0000000 --- a/go-x1 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 83dba45ab1f0f2d271e3375970ca0a7e587c94dc