From 4dae1ad2f846111b5df633b9352be0b5d9acedc9 Mon Sep 17 00:00:00 2001 From: Apratim Shukla Date: Fri, 27 Sep 2024 01:21:18 -0700 Subject: [PATCH] Sync with master (#156) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Change getvalues cmd type to getallvalues * support transfer to multi address * end * Update README.md * Update README.md * Add files via upload * Update README.md * Update README.md * Updated logo * Add files via upload * Delete img/resilientdb_logo_light-text-modern-v3-1.png * Add files via upload * Update README.md * Update README.md * Updated loqo quality * Fixed light logo bug | removed nexres refs * add mvcc for mem-kv * add history * add mvcc * add mvcc for kv * add mvcc for kv * rm unused code * remove log * remove unused log * rm unused log * add glog init * format code * Update README.md * Update README.md * Update kv_client.h * Update CHANGELOG.md * Update CHANGELOG.md * support old api command line * change license * format code * change to apache license * del file * change apache license * add notice file * change apache license * Fix the failure memory order argument to atomic_compare_exchange_strong_explicit The failure memory order cannot be release or acq_rel. Clang since llvm/llvm-project@fed5644 diagnoses an invalid argument. * Update README.md * Update copyright date in NOTICE (#129) * Use .asf.yaml to manage GitHub settings .asf.yaml is a configuration file that a project may use to control various features such as notification schemes, website staging, GitHub settings, and Pelican builds. how to use: this:https://cwiki.apache.org/confluence/display/INFRA/git+-+.asf.yaml+features↳ Set the code merge method to squash Set GitHub notifications to: commits@apache.o.g Set protected_branches * add bazel version (#132) Co-authored-by: Ubuntu * Change the deploy logging type Change a log from Info to Error which is used by the deployment scripts. * update state client to obtain the replica state * add get block numbers * fix get txn bug * add GetRequestFromReplica interface (#133) * add GetRequestFromReplica interface * fix test case failed --------- Co-authored-by: JunchaoChen * change the script path in start_contract_service.sh * Fix incorrect comment intervals in Prometheus config (#135) Co-authored-by: ic4y * kv-service python api (#136) * kv-service python api * update * update kv_operation.py route to bazel-out and update readme (#137) * update kv_operation.py route to bazel-out and update readme * update readme * Update README.md * Update README.md --------- Co-authored-by: cjcchen * ResView Branch (#138) * "Added basic data collection, pointed out spots for web socket" * "Added data gathering points and prints for testing" * "Fixed bugs with compiling stats" * "Changed message collection to be per message rather than queried periodically" * "Added conversion of stats values to JSON, need to fix replica id setting" * "Added more precision to timestamps in JSON" * "Added new data to the summary view" * "Got transaction detail collection working" * "Changed to GETALLVALUES based on main repo" * Changed Produced JSON to include txn_number * "Added websocket to send to front end, slightly inconsistent" * Add files via upload * "Added ability to receive messages from front end" * "Viewchange Update" * "Removed possible infinite loop in sending summary" * "Fixing file inclusion issue" * "Added 2 new apis in same thread to save resources" * "Adjusted make faulty endpoint" * "Removed vestigial variables, turned off faulty switch for PR" * "Fixed failing response manager test" * "Fixed issue with data carryover between instances" (#139) * add poe (#140) * Update CHANGELOG.md * Update CHANGELOG.md (#141) * add disclaimer * Fix Bug (#142) * fix viewchange bug * format code * rm unused log * rm unused log * fix ut * fix apache header * format * add apache license check workflow * add npm in workflow * Fix Apache License (#143) * add npm in workflow * test * add workflow * add path * add path * add path * add path * add path * add path * add path * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add license * add loc * add loc * add loc * fix build * add url in notice * add thirdparty license * rm rocksdb * fix name error * mv DISCLAIMER-WIP * fix typo * add version * add license in wip * Update DISCLAIMER-WIP * Update DISCLAIMER-WIP * Update README.md * civetweb * civetweb * add civetweb build * Install (#145) * add non-root install * rm unused file * add * Update README.md * Update README.md * Update README.md * Update README.md * update install * Update README.md * Update README.md * add non-root install * Update README.md * Update README.md * Update README.md * Update DISCLAIMER-WIP * Update DISCLAIMER-WIP * Update LICENSE * Update LICENSE * add license --------- Co-authored-by: Ubuntu Co-authored-by: Ubuntu * Update DISCLAIMER-WIP * Add missing ASF headers (#150) Provide dev/check-license script to perform RAT checks * Update .licenserc.yaml (#151) * Update .licenserc.yaml * add license header * add config * add config * add config * add config * add config * add config * Update README.md * Update README.md * Update README.md (#152) * Update CHANGELOG.md (#153) * Update index.js * [License]Add the missing license file (#154) * Update LICENSE --------- Co-authored-by: Gopal Nambiar Co-authored-by: Glenn Chen Co-authored-by: cjcchen Co-authored-by: ResilientDB <57961394+resilientdb@users.noreply.github.com> Co-authored-by: Ubuntu Co-authored-by: JunchaoChen Co-authored-by: AtariDreams <83477269+AtariDreams@users.noreply.github.com> Co-authored-by: Haoran Yu <75669303+Apricity001@users.noreply.github.com> Co-authored-by: Calvin Kirs Co-authored-by: Ubuntu Co-authored-by: ic4y <83933160+ic4y@users.noreply.github.com> Co-authored-by: ic4y Co-authored-by: Jiazhi Sun <123703679+NoBugInMyCode@users.noreply.github.com> Co-authored-by: Saipranav-Kotamreddy <44506064+Saipranav-Kotamreddy@users.noreply.github.com> Co-authored-by: Ubuntu Co-authored-by: Ubuntu Co-authored-by: Ubuntu Co-authored-by: JB Onofré --- .asf.yaml | 40 + .bazelversion | 1 + .github/workflows/build-push.yml | 23 +- .github/workflows/build.yml | 19 + .github/workflows/license.yml | 37 + .github/workflows/loc.yml | 33 +- .github/workflows/main.yml | 19 + .github/workflows/ut.yml | 19 + .gitignore | 2 + .licenserc.yaml | 31 + BUILD.bazel | 19 + CHANGELOG.md | 39 + CODE_OF_CONDUCT.md | 19 + DISCLAIMER-WIP | 22 + Docker/Dockerfile | 21 +- Docker/Dockerfile_mac | 19 + INSTALL.sh | 21 +- INSTALL/README.md | 62 + INSTALL/bazel/install_bazel.sh | 27 + INSTALL/protobuf/install_protobuf.sh | 20 + INSTALL_MAC.sh | 21 - LICENSE | 34 + NOTICE | 6 + README.md | 269 +++- WORKSPACE | 47 +- api/BUILD | 38 + api/README.md | 66 + api/ip_address.config | 1 + api/kv_operation.py | 46 + api/pybind_kv_service.cpp | 66 + benchmark/protocols/pbft/BUILD | 19 + .../protocols/pbft/kv_server_performance.cpp | 39 +- benchmark/protocols/pbft/kv_service_tools.cpp | 34 +- benchmark/protocols/poe/BUILD | 33 + .../protocols/poe/kv_server_performance.cpp | 83 ++ chain/state/BUILD | 20 +- chain/state/chain_state.cpp | 98 +- chain/state/chain_state.h | 54 +- chain/state/chain_state_test.cpp | 75 +- chain/storage/BUILD | 65 +- chain/storage/README.md | 13 - chain/storage/kv_storage_test.cpp | 226 ++++ chain/storage/leveldb.cpp | 290 ++++ chain/storage/leveldb.h | 81 ++ chain/storage/memory_db.cpp | 170 +++ chain/storage/memory_db.h | 88 ++ chain/storage/mock_storage.h | 52 +- chain/storage/proto/BUILD | 44 + chain/storage/proto/kv.proto | 32 + chain/storage/proto/leveldb_config.proto | 28 + chain/storage/res_leveldb.cpp | 169 --- chain/storage/res_leveldb.h | 65 - chain/storage/res_leveldb_test.cpp | 111 -- chain/storage/res_rocksdb.cpp | 171 --- chain/storage/res_rocksdb.h | 61 - chain/storage/res_rocksdb_test.cpp | 109 -- chain/storage/setting/BUILD | 35 + chain/storage/storage.h | 65 +- chain/storage/txn_memory_db.cpp | 50 - chain/storage/txn_memory_db.h | 48 - chain/storage/txn_memory_db_test.cpp | 71 - common/BUILD | 25 + common/crypto/BUILD | 19 + common/crypto/hash.cpp | 34 +- common/crypto/hash.h | 34 +- common/crypto/hash_test.cpp | 34 +- common/crypto/key_generator.cpp | 34 +- common/crypto/key_generator.h | 34 +- common/crypto/mock_signature_verifier.h | 34 +- common/crypto/signature_utils.cpp | 34 +- common/crypto/signature_utils.h | 34 +- common/crypto/signature_verifier.cpp | 34 +- common/crypto/signature_verifier.h | 34 +- .../crypto/signature_verifier_interface.cpp | 34 +- common/crypto/signature_verifier_interface.h | 34 +- common/crypto/signature_verifier_test.cpp | 34 +- common/proto/BUILD | 18 + common/proto/signature_info.proto | 19 + common/test/BUILD | 19 + common/test/json_test.cpp | 34 +- common/test/test.proto | 19 + common/test/test_macros.h | 34 +- common/utils/BUILD | 18 + common/utils/utils.cpp | 34 +- common/utils/utils.h | 34 +- dev/.rat-excludes | 19 + dev/check-license | 86 ++ documents/doxygen/Doxyfile | 8 +- documents/doxygen/DoxygenLayout.xml | 16 + documents/doxygen/doxygen_html_style.css | 20 + documents/doxygen/header | 60 + documents/doxygen/logo.png | Bin 803 -> 71672 bytes documents/file/prometheus.yml | 23 +- entrypoint.sh | 21 +- executor/common/BUILD | 18 + executor/common/custom_query.h | 34 +- executor/common/mock_transaction_manager.h | 34 +- executor/common/transaction_manager.cpp | 34 +- executor/common/transaction_manager.h | 34 +- executor/contract/executor/BUILD | 18 + .../contract/executor/contract_executor.cpp | 34 +- .../contract/executor/contract_executor.h | 34 +- .../executor/contract_executor_test.cpp | 34 +- executor/contract/executor/test_data/BUILD | 18 + executor/contract/manager/BUILD | 18 + executor/contract/manager/address_manager.cpp | 34 +- executor/contract/manager/address_manager.h | 34 +- .../contract/manager/address_manager_test.cpp | 34 +- .../contract/manager/contract_manager.cpp | 34 +- executor/contract/manager/contract_manager.h | 34 +- .../manager/contract_manager_test.cpp | 36 +- executor/contract/manager/test_data/BUILD | 18 + executor/contract/manager/utils.h | 34 +- executor/kv/BUILD | 50 +- executor/kv/kv_executor.cpp | 128 +- executor/kv/kv_executor.h | 54 +- executor/kv/kv_executor_test.cpp | 276 +++- executor/utxo/executor/BUILD | 18 + executor/utxo/executor/utxo_executor.cpp | 34 +- executor/utxo/executor/utxo_executor.h | 34 +- executor/utxo/executor/utxo_executor_test.cpp | 34 +- executor/utxo/manager/BUILD | 18 + executor/utxo/manager/transaction.cpp | 34 +- executor/utxo/manager/transaction.h | 34 +- executor/utxo/manager/transaction_test.cpp | 34 +- executor/utxo/manager/tx_mempool.cpp | 34 +- executor/utxo/manager/tx_mempool.h | 34 +- executor/utxo/manager/tx_mempool_test.cpp | 34 +- executor/utxo/manager/wallet.cpp | 34 +- executor/utxo/manager/wallet.h | 34 +- executor/utxo/manager/wallet_test.cpp | 34 +- img/apache-incubator.png | Bin 0 -> 30207 bytes img/apache-resdb.png | Bin 0 -> 98785 bytes img/resdb-v2.png | Bin 0 -> 41784 bytes img/resdb.png | Bin 0 -> 36015 bytes interface/common/BUILD | 19 + interface/common/mock_resdb_txn_accessor.h | 34 +- interface/common/resdb_state_accessor.cpp | 55 +- interface/common/resdb_state_accessor.h | 36 +- .../common/resdb_state_accessor_test.cpp | 48 +- interface/common/resdb_txn_accessor.cpp | 75 +- interface/common/resdb_txn_accessor.h | 35 +- interface/common/resdb_txn_accessor_test.cpp | 41 +- interface/contract/BUILD | 18 + interface/contract/contract_client.cpp | 34 +- interface/contract/contract_client.h | 34 +- interface/kv/BUILD | 18 + interface/kv/kv_client.cpp | 111 +- interface/kv/kv_client.h | 64 +- interface/rdbc/BUILD | 18 + interface/rdbc/mock_net_channel.h | 34 +- interface/rdbc/mock_resdb_txn_accessor.h | 34 +- interface/rdbc/net_channel.cpp | 34 +- interface/rdbc/net_channel.h | 34 +- interface/rdbc/net_channel_test.cpp | 34 +- interface/rdbc/transaction_constructor.cpp | 34 +- interface/rdbc/transaction_constructor.h | 34 +- .../rdbc/transaction_constructor_test.cpp | 34 +- interface/utxo/BUILD | 18 + interface/utxo/utxo_client.cpp | 34 +- interface/utxo/utxo_client.h | 34 +- monitoring/README.md | 19 + monitoring/prometheus/prometheus.yml | 29 +- node_modules/@actions/core/README.md | 146 -- node_modules/@actions/core/lib/command.d.ts | 16 - node_modules/@actions/core/lib/command.js | 78 -- node_modules/@actions/core/lib/command.js.map | 1 - node_modules/@actions/core/lib/core.d.ts | 116 -- node_modules/@actions/core/lib/core.js | 209 --- node_modules/@actions/core/lib/core.js.map | 1 - node_modules/@actions/core/package.json | 67 - node_modules/badgen/LICENSE.md | 5 - node_modules/badgen/README.md | 83 -- node_modules/badgen/dist/calc-text-width.d.ts | 1 - node_modules/badgen/dist/color-presets.d.ts | 14 - node_modules/badgen/dist/index.d.ts | 19 - node_modules/badgen/dist/index.js | 2 - node_modules/badgen/dist/index.js.map | 1 - node_modules/badgen/package.json | 65 - node_modules/badgen/tsconfig.json | 18 - node_modules/balanced-match/.npmignore | 5 - node_modules/balanced-match/LICENSE.md | 21 - node_modules/balanced-match/README.md | 91 -- node_modules/balanced-match/index.js | 59 - node_modules/balanced-match/package.json | 77 -- node_modules/brace-expansion/LICENSE | 21 - node_modules/brace-expansion/README.md | 129 -- node_modules/brace-expansion/index.js | 201 --- node_modules/brace-expansion/package.json | 75 -- node_modules/concat-map/.travis.yml | 4 - node_modules/concat-map/LICENSE | 18 - node_modules/concat-map/README.markdown | 62 - node_modules/concat-map/example/map.js | 6 - node_modules/concat-map/index.js | 13 - node_modules/concat-map/package.json | 88 -- node_modules/concat-map/test/map.js | 39 - node_modules/fs.realpath/LICENSE | 43 - node_modules/fs.realpath/README.md | 33 - node_modules/fs.realpath/index.js | 66 - node_modules/fs.realpath/old.js | 303 ----- node_modules/fs.realpath/package.json | 59 - node_modules/glob-gitignore/HISTORY.md | 1 - node_modules/glob-gitignore/LICENSE | 21 - node_modules/glob-gitignore/README.md | 121 -- node_modules/glob-gitignore/package.json | 85 -- node_modules/glob-gitignore/src/glob.js | 68 - node_modules/glob-gitignore/src/index.js | 15 - node_modules/glob-gitignore/src/sync.js | 50 - node_modules/glob-gitignore/src/util.js | 137 -- node_modules/glob/LICENSE | 21 - node_modules/glob/README.md | 375 ------ node_modules/glob/changelog.md | 67 - node_modules/glob/common.js | 240 ---- node_modules/glob/glob.js | 790 ----------- node_modules/glob/package.json | 80 -- node_modules/glob/sync.js | 486 ------- node_modules/ignore/CHANGELOG.md | 32 - node_modules/ignore/LICENSE-MIT | 21 - node_modules/ignore/README.md | 386 ------ node_modules/ignore/index.d.ts | 63 - node_modules/ignore/index.js | 568 -------- node_modules/ignore/legacy.js | 476 ------- node_modules/ignore/package.json | 98 -- node_modules/inflight/LICENSE | 15 - node_modules/inflight/README.md | 37 - node_modules/inflight/inflight.js | 54 - node_modules/inflight/package.json | 58 - node_modules/inherits/LICENSE | 16 - node_modules/inherits/README.md | 42 - node_modules/inherits/inherits.js | 9 - node_modules/inherits/inherits_browser.js | 27 - node_modules/inherits/package.json | 61 - node_modules/lodash.difference/LICENSE | 47 - node_modules/lodash.difference/README.md | 18 - node_modules/lodash.difference/index.js | 1170 ---------------- node_modules/lodash.difference/package.json | 69 - node_modules/lodash.union/LICENSE | 47 - node_modules/lodash.union/README.md | 18 - node_modules/lodash.union/index.js | 1181 ----------------- node_modules/lodash.union/package.json | 69 - node_modules/make-array/README.md | 61 - node_modules/make-array/index.js | 71 - node_modules/make-array/package.json | 69 - node_modules/minimatch/LICENSE | 15 - node_modules/minimatch/README.md | 209 --- node_modules/minimatch/minimatch.js | 923 ------------- node_modules/minimatch/package.json | 63 - node_modules/once/LICENSE | 15 - node_modules/once/README.md | 79 -- node_modules/once/once.js | 42 - node_modules/once/package.json | 67 - node_modules/path-is-absolute/index.js | 20 - node_modules/path-is-absolute/license | 21 - node_modules/path-is-absolute/package.json | 75 -- node_modules/path-is-absolute/readme.md | 59 - node_modules/util.inherits/HISTORY.md | 1 - node_modules/util.inherits/README.md | 45 - node_modules/util.inherits/index.js | 47 - node_modules/util.inherits/package.json | 81 -- node_modules/wrappy/LICENSE | 15 - node_modules/wrappy/README.md | 36 - node_modules/wrappy/package.json | 59 - node_modules/wrappy/wrappy.js | 33 - platform/common/data_comm/BUILD | 18 + platform/common/data_comm/data_comm.h | 34 +- platform/common/data_comm/network_comm.h | 34 +- platform/common/network/BUILD | 18 + platform/common/network/mock_socket.h | 34 +- platform/common/network/network_utils.cpp | 34 +- platform/common/network/network_utils.h | 34 +- .../common/network/network_utils_test.cpp | 34 +- platform/common/network/socket.h | 34 +- platform/common/network/tcp_socket.cpp | 34 +- platform/common/network/tcp_socket.h | 34 +- platform/common/network/tcp_socket_test.cpp | 34 +- platform/common/queue/BUILD | 18 + platform/common/queue/batch_queue.h | 34 +- platform/common/queue/batch_queue_test.cpp | 34 +- platform/common/queue/blocking_queue.h | 34 +- platform/common/queue/lock_free_queue.h | 36 +- .../common/queue/lock_free_queue_test.cpp | 34 +- platform/config/BUILD | 18 + platform/config/resdb_config.cpp | 34 +- platform/config/resdb_config.h | 34 +- platform/config/resdb_config_test.cpp | 34 +- platform/config/resdb_config_utils.cpp | 34 +- platform/config/resdb_config_utils.h | 34 +- platform/config/resdb_poc_config.cpp | 34 +- platform/config/resdb_poc_config.h | 34 +- platform/consensus/checkpoint/BUILD | 18 + platform/consensus/checkpoint/checkpoint.h | 34 +- .../consensus/checkpoint/mock_checkpoint.h | 34 +- platform/consensus/execution/BUILD | 18 + .../consensus/execution/duplicate_manager.cpp | 34 +- .../consensus/execution/duplicate_manager.h | 34 +- .../execution/geo_global_executor.cpp | 34 +- .../consensus/execution/geo_global_executor.h | 34 +- .../execution/geo_global_executor_test.cpp | 34 +- .../execution/geo_transaction_executor.cpp | 34 +- .../execution/geo_transaction_executor.h | 34 +- .../geo_transaction_executor_test.cpp | 34 +- .../execution/mock_geo_global_executor.h | 34 +- platform/consensus/execution/system_info.cpp | 34 +- platform/consensus/execution/system_info.h | 34 +- .../consensus/execution/system_info_test.cpp | 34 +- .../execution/transaction_executor.cpp | 38 +- .../execution/transaction_executor.h | 34 +- .../execution/transaction_executor_test.cpp | 34 +- platform/consensus/ordering/common/BUILD | 18 + .../consensus/ordering/common/algorithm/BUILD | 29 + .../common/algorithm/protocol_base.cpp | 65 + .../ordering/common/algorithm/protocol_base.h | 87 ++ .../consensus/ordering/common/framework/BUILD | 66 + .../ordering/common/framework/consensus.cpp | 168 +++ .../ordering/common/framework/consensus.h | 78 ++ .../common/framework/performance_manager.cpp | 276 ++++ .../common/framework/performance_manager.h | 97 ++ .../common/framework/response_manager.cpp | 236 ++++ .../common/framework/response_manager.h | 79 ++ .../common/framework/transaction_utils.cpp | 43 + .../common/framework/transaction_utils.h | 39 + .../ordering/common/transaction_utils.cpp | 34 +- .../ordering/common/transaction_utils.h | 34 +- platform/consensus/ordering/geo_pbft/BUILD | 18 + .../consensus/ordering/geo_pbft/README.md | 21 +- .../geo_pbft/consensus_manager_geo_pbft.cpp | 34 +- .../geo_pbft/consensus_manager_geo_pbft.h | 34 +- .../ordering/geo_pbft/geo_pbft_commitment.cpp | 34 +- .../ordering/geo_pbft/geo_pbft_commitment.h | 34 +- .../geo_pbft/geo_pbft_commitment_test.cpp | 34 +- .../consensus/ordering/geo_pbft/hash_set.h | 34 +- platform/consensus/ordering/pbft/BUILD | 24 +- platform/consensus/ordering/pbft/README.md | 21 +- .../ordering/pbft/checkpoint_manager.cpp | 47 +- .../ordering/pbft/checkpoint_manager.h | 40 +- .../ordering/pbft/checkpoint_manager_test.cpp | 34 +- .../consensus/ordering/pbft/commitment.cpp | 65 +- platform/consensus/ordering/pbft/commitment.h | 34 +- .../ordering/pbft/commitment_test.cpp | 34 +- .../ordering/pbft/consensus_manager_pbft.cpp | 35 +- .../ordering/pbft/consensus_manager_pbft.h | 34 +- .../pbft/lock_free_collector_pool.cpp | 34 +- .../ordering/pbft/lock_free_collector_pool.h | 34 +- .../pbft/lock_free_collector_pool_test.cpp | 34 +- .../ordering/pbft/message_manager.cpp | 39 +- .../consensus/ordering/pbft/message_manager.h | 38 +- .../ordering/pbft/mock_checkpoint_manager.h | 34 +- .../ordering/pbft/performance_manager.cpp | 45 +- .../ordering/pbft/performance_manager.h | 34 +- .../pbft/pre_very_consensus_service_pbft.h | 34 +- platform/consensus/ordering/pbft/query.cpp | 95 +- platform/consensus/ordering/pbft/query.h | 34 +- .../consensus/ordering/pbft/query_test.cpp | 44 +- .../ordering/pbft/response_manager.cpp | 149 ++- .../ordering/pbft/response_manager.h | 61 +- .../ordering/pbft/response_manager_test.cpp | 34 +- .../ordering/pbft/transaction_collector.cpp | 34 +- .../ordering/pbft/transaction_collector.h | 34 +- .../pbft/transaction_collector_test.cpp | 34 +- .../ordering/pbft/transaction_utils.cpp | 34 +- .../ordering/pbft/transaction_utils.h | 34 +- .../ordering/pbft/viewchange_manager.cpp | 40 +- .../ordering/pbft/viewchange_manager.h | 36 +- .../ordering/pbft/viewchange_manager_test.cpp | 34 +- .../consensus/ordering/poe/algorithm/BUILD | 33 + .../consensus/ordering/poe/algorithm/poe.cpp | 91 ++ .../consensus/ordering/poe/algorithm/poe.h | 59 + .../consensus/ordering/poe/framework/BUILD | 33 + .../ordering/poe/framework/consensus.cpp | 98 ++ .../ordering/poe/framework/consensus.h | 53 + platform/consensus/ordering/poe/proto/BUILD | 34 + .../ordering/poe/proto/proposal.proto | 46 + platform/consensus/recovery/BUILD | 18 + platform/consensus/recovery/recovery.cpp | 39 +- platform/consensus/recovery/recovery.h | 34 +- platform/consensus/recovery/recovery_test.cpp | 48 +- platform/networkstrate/BUILD | 18 + platform/networkstrate/README.md | 19 + platform/networkstrate/async_acceptor.cpp | 36 +- platform/networkstrate/async_acceptor.h | 34 +- .../networkstrate/async_acceptor_test.cpp | 34 +- .../networkstrate/async_replica_client.cpp | 34 +- platform/networkstrate/async_replica_client.h | 34 +- .../async_replica_client_test.cpp | 34 +- platform/networkstrate/consensus_manager.cpp | 177 +-- platform/networkstrate/consensus_manager.h | 38 +- .../networkstrate/consensus_manager_test.cpp | 34 +- .../networkstrate/mock_async_replica_client.h | 34 +- .../networkstrate/mock_replica_communicator.h | 34 +- .../networkstrate/mock_service_interface.h | 34 +- .../networkstrate/replica_communicator.cpp | 36 +- platform/networkstrate/replica_communicator.h | 34 +- .../replica_communicator_test.cpp | 34 +- platform/networkstrate/server_comm.h | 34 +- platform/networkstrate/service_interface.cpp | 34 +- platform/networkstrate/service_interface.h | 34 +- platform/networkstrate/service_network.cpp | 34 +- platform/networkstrate/service_network.h | 34 +- .../networkstrate/service_network_test.cpp | 34 +- platform/proto/BUILD | 34 +- platform/proto/broadcast.proto | 19 + platform/proto/checkpoint_info.proto | 19 + platform/proto/client_test.proto | 19 + platform/proto/durable.proto | 18 - platform/proto/logging.proto | 19 + platform/proto/network_type.proto | 19 + platform/proto/replica_info.proto | 26 +- platform/proto/resdb.proto | 34 +- platform/proto/system_info_data.proto | 19 + platform/proto/viewchange_message.proto | 19 + platform/rdbc/BUILD | 18 + platform/rdbc/acceptor.cpp | 34 +- platform/rdbc/acceptor.h | 34 +- platform/statistic/BUILD | 25 + platform/statistic/README.md | 19 + platform/statistic/prometheus_handler.cpp | 34 +- platform/statistic/prometheus_handler.h | 34 +- platform/statistic/set_random_data.cpp | 34 +- platform/statistic/stats.cpp | 262 +++- platform/statistic/stats.h | 91 +- platform/statistic/test_server.sh | 8 - platform/test/BUILD | 19 + platform/test/proto/BUILD | 19 + platform/test/proto/resdb_test.proto | 19 + platform/test/resdb_test.cpp | 36 +- platform/test/test_data/BUILD | 19 + proto/contract/BUILD | 19 + proto/contract/account.proto | 19 + proto/contract/contract.proto | 19 + proto/contract/func_params.proto | 19 + proto/contract/rpc.proto | 19 + proto/kv/BUILD | 18 + proto/kv/kv.proto | 52 +- proto/utxo/BUILD | 19 + proto/utxo/config.proto | 19 + proto/utxo/rpc.proto | 19 + proto/utxo/utxo.proto | 19 + script.js | 123 ++ scripts/deploy/README.md | 19 + .../deploy/config/kv_performance_server.conf | 10 +- scripts/deploy/config/kv_server.conf | 8 +- scripts/deploy/config/poe.config | 10 + scripts/deploy/config/template.config | 2 +- .../deploy/performance/calculate_result.py | 18 +- .../deploy/performance/pbft_performance.sh | 21 + scripts/deploy/performance/poe_performance.sh | 23 + scripts/deploy/performance/run_performance.sh | 19 +- scripts/deploy/script/deploy.sh | 42 +- scripts/deploy/script/env.sh | 19 +- scripts/deploy/script/generate_config.sh | 18 + scripts/deploy/script/generate_key.sh | 19 +- scripts/deploy/script/load_config.sh | 18 + scripts/format.sh | 20 + service/contract/BUILD | 18 + service/contract/contract_service.cpp | 34 +- service/kv/BUILD | 27 +- service/kv/kv_service.cpp | 68 +- service/tools/config/server/server.config | 12 +- service/tools/contract/README.md | 19 + service/tools/contract/api_tools/BUILD | 19 + .../contract/api_tools/contract_tools.cpp | 34 +- .../api_tools/example_contract/compile.sh | 18 + .../service_tools/start_contract_service.sh | 24 +- service/tools/kv/api_tools/BUILD | 19 + .../kv/api_tools/kv_client_txn_tools.cpp | 36 +- .../tools/kv/api_tools/kv_service_tools.cpp | 239 +++- .../tools/kv/server_tools/start_kv_service.sh | 18 + .../start_kv_service_monitoring.sh | 18 + service/tools/utxo/README.md | 18 + .../utxo/service_tools/start_utxo_service.sh | 20 +- service/tools/utxo/wallet_tool/cpp/BUILD | 19 + .../tools/utxo/wallet_tool/cpp/addr_utils.cpp | 33 +- .../tools/utxo/wallet_tool/cpp/addr_utils.h | 33 +- .../tools/utxo/wallet_tool/cpp/key_utils.cpp | 33 +- .../tools/utxo/wallet_tool/cpp/key_utils.h | 33 +- .../wallet_tool/cpp/utxo_client_tools.cpp | 97 +- service/tools/utxo/wallet_tool/py/BUILD | 19 + service/tools/utxo/wallet_tool/py/addr.py | 37 +- service/tools/utxo/wallet_tool/py/keys.py | 38 +- service/tools/utxo/wallet_tool/pybind/BUILD | 19 + .../wallet_tool/pybind/wallet_tools_py.cpp | 33 +- service/tools/utxo/wallet_tool/test/BUILD | 19 + .../tools/utxo/wallet_tool/test/key_tester.py | 37 +- .../wallet_tool/test/key_tester_utils.cpp | 34 +- service/utils/BUILD | 19 + service/utils/server_factory.cpp | 34 +- service/utils/server_factory.h | 34 +- service/utxo/BUILD | 19 + service/utxo/start_contract_server.sh | 18 + service/utxo/utxo_service.cpp | 34 +- third_party/BUILD | 40 +- third_party/asio.BUILD | 23 +- third_party/civetweb.BUILD | 22 + third_party/crow.BUILD | 23 +- third_party/date.BUILD | 25 +- third_party/eEVM.BUILD | 25 +- third_party/json.BUILD | 23 +- third_party/leveldb.BUILD | 25 +- .../loc_script/action.yml | 19 + {src => third_party/loc_script/src}/index.js | 3 +- third_party/prometheus.BUILD | 22 + third_party/rapidjson.BUILD | 22 + third_party/rocksdb.BUILD | 98 -- third_party/snappy.BUILD | 25 +- third_party/z.BUILD | 26 +- third_party/zlib.BUILD | 25 +- third_party/zstd.BUILD | 5 - tools/BUILD | 19 + tools/certificate_tools.cpp | 34 +- tools/certificate_tools_test.cpp | 34 +- tools/generate_certificate.sh | 18 + tools/generate_client.sh | 18 + tools/generate_cluster.sh | 19 +- tools/generate_key.sh | 18 + tools/generate_mulregion_config.py | 17 + tools/generate_region_config.py | 17 + tools/key_generator_tools.cpp | 34 +- tools/resdb_state_accessor_tools.cpp | 40 +- tools/resdb_txn_accessor_tools.cpp | 34 +- 519 files changed, 10933 insertions(+), 17214 deletions(-) create mode 100644 .asf.yaml create mode 100644 .bazelversion create mode 100644 .github/workflows/license.yml create mode 100644 .licenserc.yaml create mode 100644 DISCLAIMER-WIP create mode 100755 INSTALL/README.md create mode 100755 INSTALL/bazel/install_bazel.sh create mode 100755 INSTALL/protobuf/install_protobuf.sh delete mode 100644 INSTALL_MAC.sh create mode 100644 NOTICE create mode 100644 api/BUILD create mode 100644 api/README.md create mode 100644 api/ip_address.config create mode 100644 api/kv_operation.py create mode 100644 api/pybind_kv_service.cpp create mode 100644 benchmark/protocols/poe/BUILD create mode 100644 benchmark/protocols/poe/kv_server_performance.cpp delete mode 100644 chain/storage/README.md create mode 100644 chain/storage/kv_storage_test.cpp create mode 100644 chain/storage/leveldb.cpp create mode 100644 chain/storage/leveldb.h create mode 100644 chain/storage/memory_db.cpp create mode 100644 chain/storage/memory_db.h create mode 100644 chain/storage/proto/BUILD create mode 100644 chain/storage/proto/kv.proto create mode 100644 chain/storage/proto/leveldb_config.proto delete mode 100644 chain/storage/res_leveldb.cpp delete mode 100644 chain/storage/res_leveldb.h delete mode 100644 chain/storage/res_leveldb_test.cpp delete mode 100644 chain/storage/res_rocksdb.cpp delete mode 100644 chain/storage/res_rocksdb.h delete mode 100644 chain/storage/res_rocksdb_test.cpp create mode 100644 chain/storage/setting/BUILD delete mode 100644 chain/storage/txn_memory_db.cpp delete mode 100644 chain/storage/txn_memory_db.h delete mode 100644 chain/storage/txn_memory_db_test.cpp create mode 100644 dev/.rat-excludes create mode 100755 dev/check-license create mode 100644 documents/doxygen/doxygen_html_style.css create mode 100644 documents/doxygen/header create mode 100644 img/apache-incubator.png create mode 100644 img/apache-resdb.png create mode 100644 img/resdb-v2.png create mode 100644 img/resdb.png delete mode 100644 node_modules/@actions/core/README.md delete mode 100644 node_modules/@actions/core/lib/command.d.ts delete mode 100644 node_modules/@actions/core/lib/command.js delete mode 100644 node_modules/@actions/core/lib/command.js.map delete mode 100644 node_modules/@actions/core/lib/core.d.ts delete mode 100644 node_modules/@actions/core/lib/core.js delete mode 100644 node_modules/@actions/core/lib/core.js.map delete mode 100644 node_modules/@actions/core/package.json delete mode 100644 node_modules/badgen/LICENSE.md delete mode 100644 node_modules/badgen/README.md delete mode 100644 node_modules/badgen/dist/calc-text-width.d.ts delete mode 100644 node_modules/badgen/dist/color-presets.d.ts delete mode 100644 node_modules/badgen/dist/index.d.ts delete mode 100644 node_modules/badgen/dist/index.js delete mode 100644 node_modules/badgen/dist/index.js.map delete mode 100644 node_modules/badgen/package.json delete mode 100644 node_modules/badgen/tsconfig.json delete mode 100644 node_modules/balanced-match/.npmignore delete mode 100644 node_modules/balanced-match/LICENSE.md delete mode 100644 node_modules/balanced-match/README.md delete mode 100644 node_modules/balanced-match/index.js delete mode 100644 node_modules/balanced-match/package.json delete mode 100644 node_modules/brace-expansion/LICENSE delete mode 100644 node_modules/brace-expansion/README.md delete mode 100644 node_modules/brace-expansion/index.js delete mode 100644 node_modules/brace-expansion/package.json delete mode 100644 node_modules/concat-map/.travis.yml delete mode 100644 node_modules/concat-map/LICENSE delete mode 100644 node_modules/concat-map/README.markdown delete mode 100644 node_modules/concat-map/example/map.js delete mode 100644 node_modules/concat-map/index.js delete mode 100644 node_modules/concat-map/package.json delete mode 100644 node_modules/concat-map/test/map.js delete mode 100644 node_modules/fs.realpath/LICENSE delete mode 100644 node_modules/fs.realpath/README.md delete mode 100644 node_modules/fs.realpath/index.js delete mode 100644 node_modules/fs.realpath/old.js delete mode 100644 node_modules/fs.realpath/package.json delete mode 100644 node_modules/glob-gitignore/HISTORY.md delete mode 100644 node_modules/glob-gitignore/LICENSE delete mode 100644 node_modules/glob-gitignore/README.md delete mode 100644 node_modules/glob-gitignore/package.json delete mode 100644 node_modules/glob-gitignore/src/glob.js delete mode 100644 node_modules/glob-gitignore/src/index.js delete mode 100644 node_modules/glob-gitignore/src/sync.js delete mode 100644 node_modules/glob-gitignore/src/util.js delete mode 100644 node_modules/glob/LICENSE delete mode 100644 node_modules/glob/README.md delete mode 100644 node_modules/glob/changelog.md delete mode 100644 node_modules/glob/common.js delete mode 100644 node_modules/glob/glob.js delete mode 100644 node_modules/glob/package.json delete mode 100644 node_modules/glob/sync.js delete mode 100644 node_modules/ignore/CHANGELOG.md delete mode 100644 node_modules/ignore/LICENSE-MIT delete mode 100644 node_modules/ignore/README.md delete mode 100644 node_modules/ignore/index.d.ts delete mode 100644 node_modules/ignore/index.js delete mode 100644 node_modules/ignore/legacy.js delete mode 100644 node_modules/ignore/package.json delete mode 100644 node_modules/inflight/LICENSE delete mode 100644 node_modules/inflight/README.md delete mode 100644 node_modules/inflight/inflight.js delete mode 100644 node_modules/inflight/package.json delete mode 100644 node_modules/inherits/LICENSE delete mode 100644 node_modules/inherits/README.md delete mode 100644 node_modules/inherits/inherits.js delete mode 100644 node_modules/inherits/inherits_browser.js delete mode 100644 node_modules/inherits/package.json delete mode 100644 node_modules/lodash.difference/LICENSE delete mode 100644 node_modules/lodash.difference/README.md delete mode 100644 node_modules/lodash.difference/index.js delete mode 100644 node_modules/lodash.difference/package.json delete mode 100644 node_modules/lodash.union/LICENSE delete mode 100644 node_modules/lodash.union/README.md delete mode 100644 node_modules/lodash.union/index.js delete mode 100644 node_modules/lodash.union/package.json delete mode 100644 node_modules/make-array/README.md delete mode 100644 node_modules/make-array/index.js delete mode 100644 node_modules/make-array/package.json delete mode 100644 node_modules/minimatch/LICENSE delete mode 100644 node_modules/minimatch/README.md delete mode 100644 node_modules/minimatch/minimatch.js delete mode 100644 node_modules/minimatch/package.json delete mode 100644 node_modules/once/LICENSE delete mode 100644 node_modules/once/README.md delete mode 100644 node_modules/once/once.js delete mode 100644 node_modules/once/package.json delete mode 100644 node_modules/path-is-absolute/index.js delete mode 100644 node_modules/path-is-absolute/license delete mode 100644 node_modules/path-is-absolute/package.json delete mode 100644 node_modules/path-is-absolute/readme.md delete mode 100644 node_modules/util.inherits/HISTORY.md delete mode 100644 node_modules/util.inherits/README.md delete mode 100644 node_modules/util.inherits/index.js delete mode 100644 node_modules/util.inherits/package.json delete mode 100644 node_modules/wrappy/LICENSE delete mode 100644 node_modules/wrappy/README.md delete mode 100644 node_modules/wrappy/package.json delete mode 100644 node_modules/wrappy/wrappy.js create mode 100644 platform/consensus/ordering/common/algorithm/BUILD create mode 100644 platform/consensus/ordering/common/algorithm/protocol_base.cpp create mode 100644 platform/consensus/ordering/common/algorithm/protocol_base.h create mode 100644 platform/consensus/ordering/common/framework/BUILD create mode 100644 platform/consensus/ordering/common/framework/consensus.cpp create mode 100644 platform/consensus/ordering/common/framework/consensus.h create mode 100644 platform/consensus/ordering/common/framework/performance_manager.cpp create mode 100644 platform/consensus/ordering/common/framework/performance_manager.h create mode 100644 platform/consensus/ordering/common/framework/response_manager.cpp create mode 100644 platform/consensus/ordering/common/framework/response_manager.h create mode 100644 platform/consensus/ordering/common/framework/transaction_utils.cpp create mode 100644 platform/consensus/ordering/common/framework/transaction_utils.h create mode 100644 platform/consensus/ordering/poe/algorithm/BUILD create mode 100644 platform/consensus/ordering/poe/algorithm/poe.cpp create mode 100644 platform/consensus/ordering/poe/algorithm/poe.h create mode 100644 platform/consensus/ordering/poe/framework/BUILD create mode 100644 platform/consensus/ordering/poe/framework/consensus.cpp create mode 100644 platform/consensus/ordering/poe/framework/consensus.h create mode 100644 platform/consensus/ordering/poe/proto/BUILD create mode 100644 platform/consensus/ordering/poe/proto/proposal.proto delete mode 100644 platform/proto/durable.proto delete mode 100644 platform/statistic/test_server.sh create mode 100644 script.js create mode 100644 scripts/deploy/config/poe.config create mode 100755 scripts/deploy/performance/pbft_performance.sh create mode 100755 scripts/deploy/performance/poe_performance.sh rename action.yml => third_party/loc_script/action.yml (65%) rename {src => third_party/loc_script/src}/index.js (98%) delete mode 100644 third_party/rocksdb.BUILD delete mode 100644 third_party/zstd.BUILD diff --git a/.asf.yaml b/.asf.yaml new file mode 100644 index 000000000..cfb2ed0e8 --- /dev/null +++ b/.asf.yaml @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +github: + description: Global-Scale Sustainable Blockchain Fabric + #homepage: resilientdb.apache.org + labels: + - crypto + - smart-contracts + - blockchain + - solidity + - distributed-database + - key-value-database + - distributed-ledger + - blockchain-platform + - utxo + enabled_merge_buttons: + squash: true + merge: false + rebase: false + protected_branches: + master: + +notifications: + commits: commits@resilientdb.apache.org + issues: commits@resilientdb.apache.org + pullrequests: commits@resilientdb.apache.org diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 000000000..09b254e90 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +6.0.0 diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 02701aaec..e8e1460ea 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + name: ci on: @@ -30,6 +49,7 @@ jobs: with: file: ./Docker/Dockerfile context: . + platforms: linux/amd64 push: true tags: expolab/resdb:amd64 @@ -39,5 +59,6 @@ jobs: with: file: ./Docker/Dockerfile_mac context: . + platforms: linux/arm64 push: true - tags: expolab/resdb:arm64 \ No newline at end of file + tags: expolab/resdb:arm64 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 618e908f8..c1d27b4cf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + name: bazel-build CI on: diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml new file mode 100644 index 000000000..9468e3960 --- /dev/null +++ b/.github/workflows/license.yml @@ -0,0 +1,37 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +name: Check Apache License + +on: + push + +jobs: + ubuntu-build: + name: check license + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + repository: ${{github.repository}} + ref: ${{ env.BRANCH_NAME }} + + - name: Check License Header + uses: apache/skywalking-eyes/header@main diff --git a/.github/workflows/loc.yml b/.github/workflows/loc.yml index 32f331409..dc418b1e2 100644 --- a/.github/workflows/loc.yml +++ b/.github/workflows/loc.yml @@ -1,10 +1,29 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + name: LOC on: - push: - branches: + push: + branches: - master - + jobs: build: runs-on: ubuntu-latest @@ -16,9 +35,15 @@ jobs: repository: ${{github.repository}} ref: ${{ env.BRANCH_NAME }} + - name: NPM Init + run: npm init -y + + - name: NPM Install + run: npm install badgen @actions/core glob-gitignore + - name: Launch the local action - uses: ./ # Uses an action in the root directory id: badge + uses: ./third_party/loc_script/ # Uses an action in the root directory with: debug: true directory: ./ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6688d39d1..3034255fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + name: Doxygen Action on: diff --git a/.github/workflows/ut.yml b/.github/workflows/ut.yml index 86aa8573a..376bc7f85 100644 --- a/.github/workflows/ut.yml +++ b/.github/workflows/ut.yml @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + name: Unite Test on: diff --git a/.gitignore b/.gitignore index 45e1493cf..2595903f4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ bazel-* venv sdk_validator/venv __pycache__ +MODULE.* +apache_release diff --git a/.licenserc.yaml b/.licenserc.yaml new file mode 100644 index 000000000..6357ff88e --- /dev/null +++ b/.licenserc.yaml @@ -0,0 +1,31 @@ +header: + license: + spdx-id: Apache-2.0 + copyright-owner: Apache Software Foundation + + paths-ignore: + - '.*' + - '.**/**' + - 'repositories.bzl' + - 'CNAME' + - 'WORKSPACE' + - '**/*.conf' + - '**/*.config' + - '**/*.json' + - '**/*.sol' + - '**/*.pri' + - '**/*.pub' + - 'Doxyfile' + - 'header' + - 'dev/.rat-excludes' + - '**/*.md' + - 'DISCLAIMER-WIP' + - 'NOTICE' + - 'LICENSE' + - 'documents/doxygen/.gitignore' + - 'third_party/loc_script/src/index.js' + + + + comment: on-failure + diff --git a/BUILD.bazel b/BUILD.bazel index ef1087816..a2966540e 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) load("@rules_foreign_cc//foreign_cc:defs.bzl", "make") diff --git a/CHANGELOG.md b/CHANGELOG.md index 01100cbdc..b7d0c1fd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,44 @@ + + # Change Log +### Apache ResilientDB v1.10.0 ([2024-4-16](https://github.com/resilientdb/resilientdb/releases/tag/v1.10.0-rc01)) + +Add the prototype of PoE. ([Junchao Chen](https://github.com/cjcchen)) + +* Implement the base version of the Proof-of-Execution (PoE) Consensus Protocol [EDBT 2011]. + +Add ResView Data Collection and APIs ([Saipranav-Kotamreddy](https://github.com/Saipranav-Kotamreddy)) + +* Consensus data such as PBFT messages and states is now collected and stored +* Added APIs to query consensus data and progress of replicas +* Added APIs to trigger faultiness and test view change + +### NexRes v1.9.0 ([2023-11-29](https://github.com/resilientdb/resilientdb/releases/tag/nexres-v1.9.0)) + +Support Multi-version Key-Value Interface. ([Junchao Chen](https://github.com/cjcchen)) + +* Get and Set need to provide a version number to fetch the correct version of the data (if exists) or write to the correct version of data (if not overwritten already), respectively. +* Provide interfaces to obtain historical data with a specific version or a range of versions. + + ### NexRes v1.8.0 ([2023-08-21](https://github.com/resilientdb/resilientdb/releases/tag/nexres-v1.8.0)) **Implemented Enhancements:** The view-change recovery protocol was extensively expanded to support the following Byzantine failures through primary/leader replacement and replica recovery. ([Dakai Kang](https://github.com/DakaiKang)) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 3c9385001..f53ce4f0e 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,3 +1,22 @@ + + # Contributor Covenant Code of Conduct ## Our Pledge diff --git a/DISCLAIMER-WIP b/DISCLAIMER-WIP new file mode 100644 index 000000000..d94e089d8 --- /dev/null +++ b/DISCLAIMER-WIP @@ -0,0 +1,22 @@ +Apache ResilientDB is an effort undergoing incubation at the Apache Software +Foundation (ASF), sponsored by the Apache Incubator PMC. + +Incubation is required of all newly accepted projects until a further review +indicates that the infrastructure, communications, and decision making process +have stabilized in a manner consistent with other successful ASF projects. + +While incubation status is not necessarily a reflection of the completeness +or stability of the code, it does indicate that the project has yet to be +fully endorsed by the ASF. + +Some of the incubating project’s releases may not be fully compliant with ASF policy. +For example, releases may have incomplete or un-reviewed licensing conditions. +What follows is a list of known issues the project is currently aware of +(note that this list, by definition, is likely to be incomplete): + +If you are planning to incorporate this work into your product/project, please +be aware that you will need to conduct a thorough licensing review to determine +the overall implications of including this work. For the current status of this +project through the Apache Incubator visit: +https://incubator.apache.org/projects/resilientdb.html + diff --git a/Docker/Dockerfile b/Docker/Dockerfile index 31571586e..c5f82544a 100644 --- a/Docker/Dockerfile +++ b/Docker/Dockerfile @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + FROM ubuntu:20.04 ARG DEBIAN_FRONTEND=noninteractive @@ -34,4 +53,4 @@ RUN bazel --version RUN bazel build @com_github_bazelbuild_buildtools//buildifier:buildifier RUN bazel build service/tools/kv/api_tools/kv_service_tools -ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file +ENTRYPOINT ["./entrypoint.sh"] diff --git a/Docker/Dockerfile_mac b/Docker/Dockerfile_mac index 211976d87..fb629b399 100644 --- a/Docker/Dockerfile_mac +++ b/Docker/Dockerfile_mac @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + # Use a base image for ARM64 architecture FROM arm64v8/ubuntu:20.04 diff --git a/INSTALL.sh b/INSTALL.sh index c64fb0e3d..c4fdcff3e 100755 --- a/INSTALL.sh +++ b/INSTALL.sh @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + sudo apt update sudo apt install apt-transport-https curl gnupg -y sudo apt-get install protobuf-compiler -y @@ -7,7 +26,7 @@ curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg sudo mv bazel.gpg /etc/apt/trusted.gpg.d/ echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add - -sudo apt update && sudo apt install bazel=5.0.0 -y +sudo apt update && sudo apt install bazel=6.0.0 -y sudo apt install clang-format -y rm $PWD/.git/hooks/pre-push ln -s $PWD/hooks/pre-push $PWD/.git/hooks/pre-push diff --git a/INSTALL/README.md b/INSTALL/README.md new file mode 100755 index 000000000..969142a20 --- /dev/null +++ b/INSTALL/README.md @@ -0,0 +1,62 @@ + + +# Prerequire +python3.10 + +pip + +``` +sudo apt update +sudo apt-get install python3.10-dev -y +sudo apt-get install python3-dev -y +sudo apt-get install python3-pip -y +``` + +# Install Protobuf +``` +cd protobuf +./install_protobuf.sh +``` + +# Install Bazel +``` +cd bazel +wget https://github.com/bazelbuild/bazelisk/releases/download/v1.8.1/bazelisk-darwin-amd64 +chmod +x bazelisk-darwin-amd64 +mkdir -p bin +mv bazelisk-darwin-amd64 bin/bazel + +bin/bazel --version +echo "export PATH="$PATH:$PWD/bin"" >> ~/.bashrc +. ~/.bashrc +``` +or +``` +cd bazel +./install_bazel.sh +echo "export PATH="$PATH:$PWD/bin"" >> ~/.bashrc +. ~/.bashrc +``` + + +test bazel +``` +bazel --version +``` diff --git a/INSTALL/bazel/install_bazel.sh b/INSTALL/bazel/install_bazel.sh new file mode 100755 index 000000000..499de8209 --- /dev/null +++ b/INSTALL/bazel/install_bazel.sh @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +wget wget https://github.com/bazelbuild/bazelisk/releases/download/v1.8.1/bazelisk-linux-amd64 +chmod +x bazelisk-linux-amd64 +mkdir -p bin +mv bazelisk-linux-amd64 bin/bazel + +bin/bazel --version +echo "export PATH="$PATH:$PWD/bin"" >> ~/.bashrc +. ~/.bashrc diff --git a/INSTALL/protobuf/install_protobuf.sh b/INSTALL/protobuf/install_protobuf.sh new file mode 100755 index 000000000..66edc5ac7 --- /dev/null +++ b/INSTALL/protobuf/install_protobuf.sh @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pip install protobuf diff --git a/INSTALL_MAC.sh b/INSTALL_MAC.sh deleted file mode 100644 index b6d8b76da..000000000 --- a/INSTALL_MAC.sh +++ /dev/null @@ -1,21 +0,0 @@ -!/bin/sh - -sudo apt update -sudo apt install g++ -y -sudo apt install apt-transport-https curl gnupg -y -sudo apt install protobuf-compiler -y - -wget https://github.com/bazelbuild/bazelisk/releases/download/v1.8.1/bazelisk-linux-arm64 -chmod +x bazelisk-linux-arm64 -sudo mv bazelisk-linux-arm64 /usr/local/bin/bazel - -sudo apt install clang-format -y -rm -rf $PWD/.git/hooks/pre-push -ln -s $PWD/hooks/pre-push $PWD/.git/hooks/pre-push - -bazel build @com_github_bazelbuild_buildtools//buildifier:buildifier - -# for jemalloc -sudo apt-get install autoconf automake libtool -y - -sudo apt install rapidjson-dev -y diff --git a/LICENSE b/LICENSE index 261eeb9e9..ad9b5c8b3 100644 --- a/LICENSE +++ b/LICENSE @@ -199,3 +199,37 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +================================================================ + +This product includes a number of dependencies with separate copyright notices +and license terms. Your use of these submodules is subject to the terms and +conditions of the following licenses. + +================================================================ +MIT licenses +================================================================ + +third_party/loc_script/src/index.js files from https://github.com/shadowmoose/GHA-LoC-Badge/blob/1.0.0/src/index.js + +MIT License + +Copyright (c) 2020 Mike + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NOTICE b/NOTICE new file mode 100644 index 000000000..2acdbb2a6 --- /dev/null +++ b/NOTICE @@ -0,0 +1,6 @@ +Apache ResilientDB +Copyright 2023-2024 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + diff --git a/README.md b/README.md index d20ddf7cc..e46106b74 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,22 @@ + + ![](https://img.shields.io/github/v/release/resilientdb/resilientdb) ![](https://img.shields.io/badge/language-c++-orange.svg) ![](https://img.shields.io/badge/platform-Ubuntu20.0+-lightgrey.svg) @@ -12,14 +31,23 @@ **[ResilientDB](https://resilientdb.com/)** is a **High Throughput Yielding Permissioned Blockchain Fabric** founded by **[ExpoLab](https://expolab.org/)** at **[UC Davis](https://www.ucdavis.edu/)** in 2018. ResilientDB advocates a **system-centric** design by adopting a **multi-threaded architecture** that encompasses **deep pipelines**. Further, ResilientDB **separates** the ordering of client transactions from their execution, which allows it to **process messages out-of-order**. +# Downloads: +Download address for run-directly software package: https://downloads.apache.org/incubator/resilientdb/ + ### Quick Facts on ResilientDB 1. ResilientDB orders client transactions through a highly optimized implementation of the **[PBFT](https://pmg.csail.mit.edu/papers/osdi99.pdf)** [Castro and Liskov, 1998] protocol, which helps to achieve consensus among its replicas. ResilientDB also supports deploying other state-of-the-art consensus protocols *[release are planned]* such as **[GeoBFT](http://www.vldb.org/pvldb/vol13/p868-gupta.pdf)** [**[blog](https://blog.resilientdb.com/2023/03/07/GeoBFT.html), [released](https://github.com/resilientdb/resilientdb/releases/tag/nexres-v1.1.0)**], **[PoE](https://openproceedings.org/2021/conf/edbt/p111.pdf)**, **[RCC](https://arxiv.org/abs/1911.00837)**, **[RingBFT](https://openproceedings.org/2022/conf/edbt/paper-73.pdf)**, **[PoC](https://arxiv.org/abs/2302.02325)**, **[SpotLess](https://arxiv.org/abs/2302.02118)**, **[HotStuff](https://arxiv.org/abs/1803.05069)**, and **[DAG](https://arxiv.org/pdf/2105.11827.pdf)**. 2. ResilientDB requires deploying at least **3f+1** replicas, where **f (f > 0)** is the maximum number of arbitrary (or malicious) replicas. 3. ResilientDB supports primary-backup architecture, which designates one of the replicas as the **primary** (replica with identifier **0**). The primary replica initiates consensus on a client transaction, while backups agree to follow a non-malicious primary. 4. ResilientDB exposes a wide range of interfaces such as a **Key-Value** store, **Smart Contracts**, **UTXO**, and **Python SDK**. Following are some of the decentralized applications (DApps) built on top of ResilientDB: **[NFT Marketplace](https://nft.resilientdb.com/)** and **[Debitable](https://debitable.resilientdb.com/)**. -5. To persist blockchain, chain state, and metadata, ResilientDB provides durability through **LevelDB** and **RocksDB**. +5. To persist blockchain, chain state, and metadata, ResilientDB provides durability through **LevelDB**. 6. ResilientDB provides access to a seamless **GUI display** for deployment and maintenance, and supports **Grafana** for plotting monitoring data. -7. **[Historial Facts]** The ResilientDB project was founded by **[Mohammad Sadoghi](https://expolab.org/)** along with his students ([Suyash Gupta](https://gupta-suyash.github.io/index.html) as the lead Architect, [Sajjad Rahnama](https://sajjadrahnama.com/), [Jelle Hellings](https://www.jhellings.nl/)) at **[UC Davis](https://www.ucdavis.edu/)** in 2018 and was open-sourced in late 2019. On September 30, 2021, we released ResilientDB v-3.0. In 2022, ResilientDB was completely re-written and re-architected ([Junchao Chen](https://github.com/cjcchen) as the lead Architect along with the entire [NexRes Team](https://resilientdb.com/)), paving the way for a new sustainable foundation, referred to as NexRes (Next Generation ResilientDB). Thus, on September 30, 2022, NexRes-v1.0.0 was born, marking a new beginning for **[ResilientDB](https://resilientdb.com/)**. +7. **[Historial Facts]** The ResilientDB project was founded by **[Mohammad Sadoghi](https://expolab.org/)** along with his students ([Suyash Gupta](https://gupta-suyash.github.io/index.html) as the lead Architect, [Sajjad Rahnama](https://sajjadrahnama.com/) as the lead System Designer, and [Jelle Hellings](https://www.jhellings.nl/)) at **[UC Davis](https://www.ucdavis.edu/)** in 2018 and was open-sourced in late 2019. On September 30, 2021, we released ResilientDB v-3.0. In 2022, ResilientDB was completely re-written and re-architected ([Junchao Chen](https://github.com/cjcchen) as the lead Architect, [Dakai Kang](https://github.com/DakaiKang) as the lead Recovery Architect along with the entire [NexRes Team](https://expolab.resilientdb.com/)), paving the way for a new sustainable foundation, referred to as NexRes (Next Generation ResilientDB). Thus, on September 30, 2022, NexRes-v1.0.0 was born, marking a new beginning for **[ResilientDB](https://resilientdb.com/)**. On October 21, 2023, **[ResilientDB](https://cwiki.apache.org/confluence/display/INCUBATOR/ResilientDBProposal)** was officially accepted into **[Apache Incubation](https://incubator.apache.org/projects/resilientdb.html)**. + +
+ + + +
--- @@ -44,10 +72,12 @@ The latest ResilientDB documentation, including a programming guide, is availabl - System Parameters & Configuration - Continuous Integration & Testing -![Nexres](./img/nexres.png) +
+ +
## OS Requirements -Ubuntu 20.* +Ubuntu 20+ --- @@ -59,6 +89,7 @@ Install dependencies: ./INSTALL.sh +For non-root users, see [INSTALL/README.md](https://github.com/apache/incubator-resilientdb/blob/master/INSTALL/README.md) Run ResilientDB (Providing a Key-Value Service): @@ -70,29 +101,219 @@ Build Interactive Tools: bazel build service/tools/kv/api_tools/kv_service_tools -Run tools to set a value by a key (for example, set the value with key "test" and value "test_value"): +## Functions ## +ResilientDB supports two types of functions: version-based and non-version-based. +Version-based functions will leverage versions to protect each update, versions must be obtained before updating a key. - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config set test test_value - -You will see the following result if successful: +***Note***: Version-based functions are not compatible with non-version-based functions. Do not use both in your applications. - client set ret = 0 +We show the functions below and show how to use [kv_service_tools](service/tools/kv/api_tools/kv_service_tools.cpp) to test the function. -Run tools to get value by a key (for example, get the value with key "test"): +### Version-Based Functions ### +#### Get #### +Obtain the value of `key` with a specific version `v`. - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config get test - -You will see the following result if successful: + kv_service_tools --config config_file --cmd get_with_version --key key --version v + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_with_version | +| key | the key you want to obtain | +| version | the version you want to obtain. (If the `v` is 0, it will return the latest version | + + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_with_version --key key1 --version 0 + +Results: +> get key = key1, value = value: "v2" +> version: 2 + +#### Set #### +Set `value` to the key `key` based on version `v`. + + kv_service_tools --config config_file --cmd set_with_version --key key --version v --value value + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | set_with_version | +| key | the key you want to set | +| version | the version you have obtained. (If the version has been changed during the update, the transaction will be ignored) | +| value | the new value | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd set_with_version --key key1 --version 0 --value v1 + +Results: +> set key = key1, value = v3, version = 2 done, ret = 0 +> +> current value = value: "v3" +> version: 3 + +#### Get Key History #### +Obtain the update history of key `key` within the versions [`v1`, `v2`]. + + kv_service_tools --config config_file --cmd get_history --key key --min_version v1 --max_version v2 + + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_history | +| key | the key you want to obtain | +| min_version | the minimum version you want to obtain | +| max_version | the maximum version you want to obtain | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_history --key key1 --min_version 1 --max_version 2 + +Results: + +> get history key = key1, min version = 1, max version = 2
+> value =
+> item {
+>   key: "key1"
+>   value_info {
+>    value: "v1"
+>    version: 2
+>  }
+> }
+> item {
+>   key: "key1"
+>   value_info {
+>    value: "v0"
+>    version: 1
+>  }
+> } + +#### Get Top #### +Obtain the recent `top_number` history of the key `key`. + + kv_service_tools --config config_path --cmd get_top --key key --top top_number + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_top | +| key | the key you want to obtain | +| top | the number of the recent updates | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_top --key key1 --top 1 + +Results: - client get value = test_value +>key = key1, top 1
+> value =
+> item {
+> key: "key1"
+>  value_info {
+>    value: "v2"
+>    version: 3
+>  }
+>} -Run tools to get all values that have been set: +#### Get Key Range #### +Obtain the values of the keys in the ranges [`key1`, `key2`]. Do not use this function in your practice code - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config getvalues + kv_service_tools --config config_file --cmd get_key_range_with_version --min_key key1 --max_key key2 -You will see the following result if successful: +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_key_range_with_version | +| min_key | the minimum key | +| max_key | the maximum key | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_key_range_with_version --min_key key1 --max_key key3 + +Results: + +>min key = key1 max key = key2
+> getrange value =
+> item {
+>   key: "key1"
+>   value_info {
+>    value: "v0"
+>    version: 1
+>   }
+> }
+> item {
+>   key: "key2"
+>   value_info {
+>    value: "v1"
+>    version: 1
+>   }
+>} + + +### Non-Version-Based Function ### +#### Set ##### +Set `value` to the key `key`. + + kv_service_tools --config config_file --cmd set --key key --value value + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | set | +| key | the key you want to set | +| value | the new value | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd set --key key1 --value value1 + +Results: +> set key = key1, value = v1, done, ret = 0 + +#### Get #### +Obtain the value of `key`. + + kv_service_tools --config config_file --cmd get --key key + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get | +| key | the key you want to obtain | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get --key key1 + +Results: +> get key = key1, value = "v2" + + +#### Get Key Range #### +Obtain the values of the keys in the ranges [`key1`, `key2`]. Do not use this function in your practice code + + kv_service_tools --config config_path --cmd get_key_range --min_key key1 --max_key key2 + +| parameters | descriptions | +| ---- | ---- | +| config | the path of the client config which points to the db entrance | +| cmd | get_key_range | +| min_key | the minimum key | +| max_key | the maximum key | + +Example: + + bazel-bin/service/tools/kv/api_tools/kv_service_tools --config service/tools/config/interface/service.config --cmd get_key_range --min_key key1 --max_key key3 + +Results: +> getrange min key = key1, max key = key3
+> value = [v3,v2,v1] - client getvalues value = [test_value] ## Deployment Script @@ -135,14 +356,4 @@ We also provide access to a [deployment script](https://github.com/resilientdb/r docker exec -it myserver bash ``` - Verify the functionality of the service by performing set and get operations: - - - Set a test value: - ```shell - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config set test test_value - ``` - - - Retrieve the test value: - ``` - bazel-bin/service/tools/kv/api_tools/kv_service_tools service/tools/config/interface/service.config get test - ``` \ No newline at end of file + Verify the functionality of the service by performing set and get operations provided above [functions](README.md#functions). diff --git a/WORKSPACE b/WORKSPACE index 317fefbfa..93a66164b 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -140,8 +140,6 @@ http_archive( ], ) -#prometheus cpp client library - http_archive( name = "com_google_leveldb", build_file = "@com_resdb_nexres//third_party:leveldb.BUILD", @@ -176,30 +174,10 @@ http_archive( url = "https://github.com/madler/zlib/archive/v1.2.11.tar.gz", ) -bind( - name = "zstd", - actual = "//third_party:zstd", -) - -http_archive( - name = "com_facebook_zstd", - build_file_content = all_content, - strip_prefix = "zstd-1.5.2", - url = "https://github.com/facebook/zstd/archive/refs/tags/v1.5.2.zip", -) - -http_archive( - name = "com_github_facebook_rocksdb", - build_file = "@com_resdb_nexres//third_party:rocksdb.BUILD", - sha256 = "928cbd416c0531e9b2e7fa74864ce0d7097dca3f5a8c31f31459772a28dbfcba", - strip_prefix = "rocksdb-7.2.2", - url = "https://github.com/facebook/rocksdb/archive/refs/tags/v7.2.2.zip", -) - http_archive( name = "pybind11_bazel", - strip_prefix = "pybind11_bazel-master", - urls = ["https://github.com/pybind/pybind11_bazel/archive/master.zip"], + strip_prefix = "pybind11_bazel-2.11.1.bzl.1", + urls = ["https://github.com/pybind/pybind11_bazel/archive/refs/tags/v2.11.1.bzl.1.zip"], ) http_archive( @@ -224,3 +202,24 @@ http_archive( strip_prefix = "json-3.9.1", urls = ["https://github.com/nlohmann/json/archive/v3.9.1.tar.gz"], ) + +http_archive( + name = "com_crowcpp_crow", + build_file = "//third_party:crow.BUILD", + sha256 = "f95128a8976fae6f2922823e07da59edae277a460776572a556a4b663ff5ee4b", + strip_prefix = "Crow-1.0-5", + url = "https://github.com/CrowCpp/Crow/archive/refs/tags/v1.0+5.zip", +) + +bind( + name = "asio", + actual = "@com_chriskohlhoff_asio//:asio", +) + +http_archive( + name = "com_chriskohlhoff_asio", + build_file = "//third_party:asio.BUILD", + sha256 = "babcdfd2c744905a73d20de211b51367bda0d5200f11d654c4314b909d8c963c", + strip_prefix = "asio-asio-1-26-0", + url = "https://github.com/chriskohlhoff/asio/archive/refs/tags/asio-1-26-0.zip", +) diff --git a/api/BUILD b/api/BUILD new file mode 100644 index 000000000..5bad893ba --- /dev/null +++ b/api/BUILD @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +package(default_visibility = ["//visibility:public"]) + +cc_binary( + name = "pybind_kv.so", + srcs = ["pybind_kv_service.cpp"], + linkshared = 1, + linkstatic = 1, + deps = [ + "@//common/proto:signature_info_cc_proto", + "@//interface/kv:kv_client", + "@//platform/config:resdb_config_utils", + "@pybind11", + ], +) + +py_library( + name = "pybind_kv_so", + data = [":pybind_kv.so"], + imports = ["."], +) diff --git a/api/README.md b/api/README.md new file mode 100644 index 000000000..d25474f30 --- /dev/null +++ b/api/README.md @@ -0,0 +1,66 @@ + + +# ResilientDB kv-Service Python API(Get and Set Command) + +## Description +This API allows users to use kv-service of the ResilientDB in Python directly. + +## How to Run +1. Make sure to run `./INSTALL.sh` in advance. +1. cd to `incubator-resilientdb/api` folder. +2. Run command `bazel build :pybind_kv_so`. +3. From `kv_operation.py`, import `get_value` and `set_value` functions into your Python file to use it (Make sure to use the same Python version when running `bazel build` command and calling the functions). + +## Parameters +### `set_value`: +1. `key`: The key user wants to store in a key-value pair. Acceptable types are `str`, `int`, `float`. +2. `value`: The corresponding value to `key` in the key-value pair. Acceptable types are `str`, `int`, `float`. +3. config_path (optional): The path to the user's blockchain config file (IP addresses). If the user does not specify this parameter, the system will default to the address located in "ip.address.config." The acceptable type is `str`. +4. `return`: `True` if `value` has been set successfully; otherwise, `value` has not been set successfully. +### `get_value`: +1. `key`: The key user wants to get in a key-value pair. Acceptable types are `str`, `int`, `float`. +2. `return`: `\n` if the corresponding value of `key` is empty, otherwise is the corresponding value of `key`. + + +## Example +```angular2html +import sys +# Your path to ResilientDB api folder +sys.path.append("/home/ubuntu/Desktop/incubator-resilientdb/api") +from kv_operation import set_value, get_value + +set_value("test", "111222") +get_value("test") +``` + +If having set up the environment parameter, "sys.path" can be ignorred. +``` +export PYTHON_PATH="/home/ubuntu/Desktop/incubator-resilientdb/api":PYTHON_PATH +``` +```angular2html +from kv_operation import set_value, get_value + +set_value("test", "111222") +get_value("test") +``` + + + + diff --git a/api/ip_address.config b/api/ip_address.config new file mode 100644 index 000000000..e119673ea --- /dev/null +++ b/api/ip_address.config @@ -0,0 +1 @@ +5 44.193.63.142 17005 \ No newline at end of file diff --git a/api/kv_operation.py b/api/kv_operation.py new file mode 100644 index 000000000..f18c84601 --- /dev/null +++ b/api/kv_operation.py @@ -0,0 +1,46 @@ +# + # Licensed to the Apache Software Foundation (ASF) under one + # or more contributor license agreements. See the NOTICE file + # distributed with this work for additional information + # regarding copyright ownership. The ASF licenses this file + # to you under the Apache License, Version 2.0 (the + # "License"); you may not use this file except in compliance + # with the License. You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, + # software distributed under the License is distributed on an + # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + # KIND, either express or implied. See the License for the + # specific language governing permissions and limitations + # under the License. + # + +import os +import sys +current_file_path = os.path.abspath(__file__) +current_dir = os.path.dirname(current_file_path) +parent_dir = os.path.dirname(current_dir) +new_path_dir = os.path.join(parent_dir, "bazel-out", "k8-fastbuild", "bin", "api") +sys.path.insert(0, new_path_dir) +import pybind_kv + + +def set_value(key: str or int or float, value: str or int or float, config_path: str = current_dir + "/ip_address.config") -> bool: + """ + :param key: The key you want to set your value to. + :param value: The key's corresponding value in key value pair. + :param config_path: Default is connect to the main chain, users can specify the path to connect to their local blockchain. + :return: True if value has been set successfully. + """ + return pybind_kv.set(str(key), str(value), os.path.abspath(config_path)) + + +def get_value(key: str or int or float, config_path: str = current_dir + "/ip_address.config") -> str: + """ + :param key: The key of the value you want to get in key value pair. + :param config_path: Default is connect to the main chain, users can specify the path to connect to their local blockchain. + :return: A string of the key's corresponding value. + """ + return pybind_kv.get(str(key), os.path.abspath(config_path)) diff --git a/api/pybind_kv_service.cpp b/api/pybind_kv_service.cpp new file mode 100644 index 000000000..013683fbd --- /dev/null +++ b/api/pybind_kv_service.cpp @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "common/proto/signature_info.pb.h" +#include "interface/kv/kv_client.h" +#include "platform/config/resdb_config_utils.h" + +using resdb::GenerateReplicaInfo; +using resdb::GenerateResDBConfig; +using resdb::KVClient; +using resdb::ReplicaInfo; +using resdb::ResDBConfig; + +std::string get(std::string key, std::string config_path) { + ResDBConfig config = GenerateResDBConfig(config_path); + config.SetClientTimeoutMs(100000); + KVClient client(config); + auto result_ptr = client.Get(key); + if (result_ptr) { + return *result_ptr; + } else { + return ""; + } +} + +bool set(std::string key, std::string value, std::string config_path) { + ResDBConfig config = GenerateResDBConfig(config_path); + config.SetClientTimeoutMs(100000); + KVClient client(config); + int result = client.Set(key, value); + if (result == 0) { + return true; + } else { + return false; + } +} + +PYBIND11_MODULE(pybind_kv, m) { + m.def("get", &get, "A function that gets a value from the key-value store"); + m.def("set", &set, "A function that sets a value in the key-value store"); +} diff --git a/benchmark/protocols/pbft/BUILD b/benchmark/protocols/pbft/BUILD index 456d6d4c0..f99e82062 100644 --- a/benchmark/protocols/pbft/BUILD +++ b/benchmark/protocols/pbft/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:private"]) load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") @@ -6,6 +24,7 @@ cc_binary( name = "kv_server_performance", srcs = ["kv_server_performance.cpp"], deps = [ + "//chain/storage:memory_db", "//executor/kv:kv_executor", "//platform/config:resdb_config_utils", "//platform/consensus/ordering/pbft:consensus_manager_pbft", diff --git a/benchmark/protocols/pbft/kv_server_performance.cpp b/benchmark/protocols/pbft/kv_server_performance.cpp index 8efd5b932..7a81f27c7 100644 --- a/benchmark/protocols/pbft/kv_server_performance.cpp +++ b/benchmark/protocols/pbft/kv_server_performance.cpp @@ -1,31 +1,25 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include -#include "chain/state/chain_state.h" +#include "chain/storage/memory_db.h" #include "executor/kv/kv_executor.h" #include "platform/config/resdb_config_utils.h" #include "platform/consensus/ordering/pbft/consensus_manager_pbft.h" @@ -34,6 +28,7 @@ #include "proto/kv/kv.pb.h" using namespace resdb; +using namespace resdb::storage; void ShowUsage() { printf(" [logging_dir]\n"); @@ -69,7 +64,7 @@ int main(int argc, char** argv) { config->RunningPerformance(true); auto performance_consens = std::make_unique( - *config, std::make_unique(std::make_unique())); + *config, std::make_unique(std::make_unique())); performance_consens->SetupPerformanceDataFunc([]() { KVRequest request; request.set_cmd(KVRequest::SET); diff --git a/benchmark/protocols/pbft/kv_service_tools.cpp b/benchmark/protocols/pbft/kv_service_tools.cpp index 17858ef21..43627b34f 100644 --- a/benchmark/protocols/pbft/kv_service_tools.cpp +++ b/benchmark/protocols/pbft/kv_service_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/benchmark/protocols/poe/BUILD b/benchmark/protocols/poe/BUILD new file mode 100644 index 000000000..7f1cc05ec --- /dev/null +++ b/benchmark/protocols/poe/BUILD @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +package(default_visibility = ["//visibility:private"]) + +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") + +cc_binary( + name = "kv_server_performance", + srcs = ["kv_server_performance.cpp"], + deps = [ + "//chain/storage:memory_db", + "//executor/kv:kv_executor", + "//platform/config:resdb_config_utils", + "//platform/consensus/ordering/poe/framework:consensus", + "//service/utils:server_factory", + ], +) diff --git a/benchmark/protocols/poe/kv_server_performance.cpp b/benchmark/protocols/poe/kv_server_performance.cpp new file mode 100644 index 000000000..90a220a1f --- /dev/null +++ b/benchmark/protocols/poe/kv_server_performance.cpp @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +#include "chain/storage/memory_db.h" +#include "executor/kv/kv_executor.h" +#include "platform/config/resdb_config_utils.h" +#include "platform/consensus/ordering/poe/framework/consensus.h" +#include "platform/networkstrate/service_network.h" +#include "platform/statistic/stats.h" +#include "proto/kv/kv.pb.h" + +using namespace resdb; +using namespace resdb::poe; +using namespace resdb::storage; + +void ShowUsage() { + printf(" [logging_dir]\n"); +} + +std::string GetRandomKey() { + int num1 = rand() % 10; + int num2 = rand() % 10; + return std::to_string(num1) + std::to_string(num2); +} + +int main(int argc, char** argv) { + if (argc < 3) { + ShowUsage(); + exit(0); + } + + // google::InitGoogleLogging(argv[0]); + // FLAGS_minloglevel = google::GLOG_WARNING; + + char* config_file = argv[1]; + char* private_key_file = argv[2]; + char* cert_file = argv[3]; + + if (argc >= 5) { + auto monitor_port = Stats::GetGlobalStats(5); + monitor_port->SetPrometheus(argv[4]); + } + + std::unique_ptr config = + GenerateResDBConfig(config_file, private_key_file, cert_file); + + config->RunningPerformance(true); + ResConfigData config_data = config->GetConfigData(); + + auto performance_consens = std::make_unique( + *config, std::make_unique(std::make_unique())); + performance_consens->SetupPerformanceDataFunc([]() { + KVRequest request; + request.set_cmd(KVRequest::SET); + request.set_key(GetRandomKey()); + request.set_value("helloword"); + std::string request_data; + request.SerializeToString(&request_data); + return request_data; + }); + + auto server = + std::make_unique(*config, std::move(performance_consens)); + server->Run(); +} diff --git a/chain/state/BUILD b/chain/state/BUILD index 900212ddc..f4bcde57f 100644 --- a/chain/state/BUILD +++ b/chain/state/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( @@ -5,8 +23,8 @@ cc_library( srcs = ["chain_state.cpp"], hdrs = ["chain_state.h"], deps = [ - "//chain/storage", "//common:comm", + "//platform/proto:resdb_cc_proto", ], ) diff --git a/chain/state/chain_state.cpp b/chain/state/chain_state.cpp index 98a82e6b6..18eaed71b 100644 --- a/chain/state/chain_state.cpp +++ b/chain/state/chain_state.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "chain/state/chain_state.h" @@ -29,64 +23,22 @@ namespace resdb { -ChainState::ChainState(std::unique_ptr storage) - : storage_(std::move(storage)) {} - -Storage* ChainState::GetStorage() { - return storage_ ? storage_.get() : nullptr; -} +ChainState::ChainState() : max_seq_(0) {} -int ChainState::SetValue(const std::string& key, const std::string& value) { - if (storage_) { - return storage_->SetValue(key, value); +Request* ChainState::Get(uint64_t seq) { + std::unique_lock lk(mutex_); + if (data_.find(seq) == data_.end()) { + return nullptr; } - kv_map_[key] = value; - return 0; + return data_[seq].get(); } -std::string ChainState::GetValue(const std::string& key) { - if (storage_) { - return storage_->GetValue(key); - } - auto search = kv_map_.find(key); - if (search != kv_map_.end()) - return search->second; - else { - return ""; - } +void ChainState::Put(std::unique_ptr request) { + std::unique_lock lk(mutex_); + max_seq_ = request->seq(); + data_[max_seq_] = std::move(request); } -std::string ChainState::GetAllValues(void) { - if (storage_) { - return storage_->GetAllValues(); - } - std::string values = "["; - bool first_iteration = true; - for (auto kv : kv_map_) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(kv.second); - } - values.append("]"); - return values; -} - -std::string ChainState::GetRange(const std::string& min_key, - const std::string& max_key) { - if (storage_) { - return storage_->GetRange(min_key, max_key); - } - std::string values = "["; - bool first_iteration = true; - for (auto kv : kv_map_) { - if (kv.first >= min_key && kv.first <= max_key) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(kv.second); - } - } - values.append("]"); - return values; -} +uint64_t ChainState::GetMaxSeq() { return max_seq_; } } // namespace resdb diff --git a/chain/state/chain_state.h b/chain/state/chain_state.h index e2671ab59..697b1afcb 100644 --- a/chain/state/chain_state.h +++ b/chain/state/chain_state.h @@ -1,50 +1,42 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once -#include +#include #include -#include "chain/storage/storage.h" +#include "platform/proto/resdb.pb.h" namespace resdb { class ChainState { public: - ChainState(std::unique_ptr storage = nullptr); - int SetValue(const std::string& key, const std::string& value); - std::string GetValue(const std::string& key); - std::string GetAllValues(void); - std::string GetRange(const std::string& min_key, const std::string& max_key); - - Storage* GetStorage(); + ChainState(); + Request* Get(uint64_t seq); + void Put(std::unique_ptr request); + uint64_t GetMaxSeq(); private: - std::unique_ptr storage_ = nullptr; - std::unordered_map kv_map_; + std::mutex mutex_; + std::unordered_map > data_; + std::atomic max_seq_; }; } // namespace resdb diff --git a/chain/state/chain_state_test.cpp b/chain/state/chain_state_test.cpp index 0d0fda1e4..7fd3fbe19 100644 --- a/chain/state/chain_state_test.cpp +++ b/chain/state/chain_state_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "chain/state/chain_state.h" @@ -28,25 +22,42 @@ #include #include +#include "common/test/test_macros.h" + namespace resdb { namespace { -TEST(KVServerExecutorTest, SetValue) { - ChainState state; +using ::resdb::testing::EqualsProto; +using ::testing::Pointee; + +TEST(ChainStateTest, GetEmptyValue) { + ChainState db; + EXPECT_EQ(db.Get(1), nullptr); +} - EXPECT_EQ(state.GetAllValues(), "[]"); - EXPECT_EQ(state.SetValue("test_key", "test_value"), 0); - EXPECT_EQ(state.GetValue("test_key"), "test_value"); +TEST(ChainStateTest, GetValue) { + Request request; + request.set_seq(1); + request.set_data("test"); - // GetValues and GetRange may be out of order for in-memory, so we test up to - // 1 key-value pair - EXPECT_EQ(state.GetAllValues(), "[test_value]"); - EXPECT_EQ(state.GetRange("a", "z"), "[test_value]"); + ChainState db; + db.Put(std::make_unique(request)); + EXPECT_THAT(db.Get(1), Pointee(EqualsProto(request))); } -TEST(KVServerExecutorTest, GetValue) { - ChainState state; - EXPECT_EQ(state.GetValue("test_key"), ""); +TEST(ChainStateTest, GetSecondValue) { + Request request; + request.set_seq(1); + request.set_data("test"); + + ChainState db; + db.Put(std::make_unique(request)); + + request.set_seq(1); + request.set_data("test_1"); + db.Put(std::make_unique(request)); + + EXPECT_THAT(db.Get(1), Pointee(EqualsProto(request))); } } // namespace diff --git a/chain/storage/BUILD b/chain/storage/BUILD index 0a0c8e7ff..19108fa99 100644 --- a/chain/storage/BUILD +++ b/chain/storage/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( @@ -16,55 +34,34 @@ cc_library( ) cc_library( - name = "res_leveldb", - srcs = ["res_leveldb.cpp"], - hdrs = ["res_leveldb.h"], + name = "memory_db", + srcs = ["memory_db.cpp"], + hdrs = ["memory_db.h"], deps = [ ":storage", "//common:comm", - "//platform/proto:replica_info_cc_proto", - "//third_party:leveldb", - ], -) - -cc_test( - name = "res_leveldb_test", - srcs = ["res_leveldb_test.cpp"], - deps = [ - ":res_leveldb", - "//common/test:test_main", ], ) cc_library( - name = "res_rocksdb", - srcs = ["res_rocksdb.cpp"], - hdrs = ["res_rocksdb.h"], - tags = ["manual"], + name = "leveldb", + srcs = ["leveldb.cpp"], + hdrs = ["leveldb.h"], deps = [ ":storage", + "//chain/storage/proto:kv_cc_proto", + "//chain/storage/proto:leveldb_config_cc_proto", "//common:comm", - "//platform/proto:replica_info_cc_proto", - "//third_party:rocksdb", + "//third_party:leveldb", ], ) cc_test( - name = "res_rocksdb_test", - srcs = ["res_rocksdb_test.cpp"], - tags = ["manual"], + name = "kv_storage_test", + srcs = ["kv_storage_test.cpp"], deps = [ - ":res_rocksdb", + ":leveldb", + ":memory_db", "//common/test:test_main", ], ) - -cc_library( - name = "txn_memory_db", - srcs = ["txn_memory_db.cpp"], - hdrs = ["txn_memory_db.h"], - deps = [ - "//common:comm", - "//platform/proto:resdb_cc_proto", - ], -) diff --git a/chain/storage/README.md b/chain/storage/README.md deleted file mode 100644 index 033b0517b..000000000 --- a/chain/storage/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Durable layer -## How to use -Look at [proto/durable.proto](https://github.com/msadoghi/nexres/blob/master/proto/durable.proto) and [proto/replica_info.proto](https://github.com/msadoghi/nexres/blob/master/proto/replica_info.proto) for how to format the durability settings. - -A config file for 4 replicas on localhost can be found at [config/example/kv_config.config](https://github.com/msadoghi/nexres/blob/master/example/kv_config.config). - -## Warning - -If "path" is not set in the durability settings for RocksDB or LevelDB then default paths will be generated in the /tmp/ folder, which is cleared whenever the machine is shut down. - -If you are testing Nexres on your local machine using localhost ip, then make sure to set generate_unique_pathnames to true, because multiple processes are not allowed to open up the same RocksDB/LevelDB directory at the same time. When generate_unique_pathnames is set to true, the durable layer uses the cert file names to generate separate directories for each port of the localhost ip. - -For example, the process hosting a server with cert_1.cert will append "1" to its directory path. If the cert file name does not contain a number and generate_unique_pathnames is set, "0" will be appended to the path. diff --git a/chain/storage/kv_storage_test.cpp b/chain/storage/kv_storage_test.cpp new file mode 100644 index 000000000..fd8c4bfdb --- /dev/null +++ b/chain/storage/kv_storage_test.cpp @@ -0,0 +1,226 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include + +#include + +#include "chain/storage/leveldb.h" +#include "chain/storage/memory_db.h" + +namespace resdb { +namespace storage { +namespace { + +enum StorageType { + MEM = 0, + LEVELDB = 1, +}; + +class KVStorageTest : public ::testing::TestWithParam { + protected: + KVStorageTest() { + StorageType t = GetParam(); + switch (t) { + case MEM: + storage = NewMemoryDB(); + break; + case LEVELDB: + Reset(); + storage = NewResLevelDB(path_); + break; + } + } + + private: + void Reset() { std::filesystem::remove_all(path_.c_str()); } + + protected: + std::unique_ptr storage; + std::string path_ = "/tmp/leveldb_test"; +}; + +TEST_P(KVStorageTest, SetValue) { + EXPECT_EQ(storage->SetValue("test_key", "test_value"), 0); + EXPECT_EQ(storage->GetValue("test_key"), "test_value"); +} + +TEST_P(KVStorageTest, GetValue) { + EXPECT_EQ(storage->GetValue("test_key"), ""); +} + +TEST_P(KVStorageTest, GetEmptyValueWithVersion) { + EXPECT_EQ(storage->GetValueWithVersion("test_key", 0), + std::make_pair(std::string(""), 0)); +} + +TEST_P(KVStorageTest, SetValueWithVersion) { + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value", 1), -2); + + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value", 0), 0); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 0), + std::make_pair(std::string("test_value"), 1)); + EXPECT_EQ(storage->GetValueWithVersion("test_key", 1), + std::make_pair(std::string("test_value"), 1)); + + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value_v2", 2), -2); + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value_v2", 1), 0); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 0), + std::make_pair(std::string("test_value_v2"), 2)); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 1), + std::make_pair(std::string("test_value"), 1)); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 2), + std::make_pair(std::string("test_value_v2"), 2)); + + EXPECT_EQ(storage->GetValueWithVersion("test_key", 3), + std::make_pair(std::string("test_value_v2"), 2)); +} + +TEST_P(KVStorageTest, GetAllValueWithVersion) { + { + std::map > expected_list{ + std::make_pair("test_key", std::make_pair("test_value", 1))}; + + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value", 0), 0); + EXPECT_EQ(storage->GetAllItems(), expected_list); + } + + { + std::map > expected_list{ + std::make_pair("test_key", std::make_pair("test_value_v2", 2))}; + EXPECT_EQ(storage->SetValueWithVersion("test_key", "test_value_v2", 1), 0); + EXPECT_EQ(storage->GetAllItems(), expected_list); + } + + { + std::map > expected_list{ + std::make_pair("test_key_v1", std::make_pair("test_value1", 1)), + std::make_pair("test_key", std::make_pair("test_value_v2", 2))}; + EXPECT_EQ(storage->SetValueWithVersion("test_key_v1", "test_value1", 0), 0); + EXPECT_EQ(storage->GetAllItems(), expected_list); + } +} + +TEST_P(KVStorageTest, GetKeyRange) { + EXPECT_EQ(storage->SetValueWithVersion("1", "value1", 0), 0); + EXPECT_EQ(storage->SetValueWithVersion("2", "value2", 0), 0); + EXPECT_EQ(storage->SetValueWithVersion("3", "value3", 0), 0); + EXPECT_EQ(storage->SetValueWithVersion("4", "value4", 0), 0); + + { + std::map > expected_list{ + std::make_pair("1", std::make_pair("value1", 1)), + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3", 1)), + std::make_pair("4", std::make_pair("value4", 1))}; + EXPECT_EQ(storage->GetKeyRange("1", "4"), expected_list); + } + + EXPECT_EQ(storage->SetValueWithVersion("3", "value3_1", 1), 0); + { + std::map > expected_list{ + std::make_pair("1", std::make_pair("value1", 1)), + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + std::make_pair("4", std::make_pair("value4", 1))}; + EXPECT_EQ(storage->GetKeyRange("1", "4"), expected_list); + } + { + std::map > expected_list{ + std::make_pair("1", std::make_pair("value1", 1)), + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + }; + EXPECT_EQ(storage->GetKeyRange("1", "3"), expected_list); + } + { + std::map > expected_list{ + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + std::make_pair("4", std::make_pair("value4", 1))}; + EXPECT_EQ(storage->GetKeyRange("2", "4"), expected_list); + } + { + std::map > expected_list{ + std::make_pair("1", std::make_pair("value1", 1)), + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + std::make_pair("4", std::make_pair("value4", 1))}; + EXPECT_EQ(storage->GetKeyRange("0", "5"), expected_list); + } + { + std::map > expected_list{ + std::make_pair("2", std::make_pair("value2", 1)), + std::make_pair("3", std::make_pair("value3_1", 2)), + }; + EXPECT_EQ(storage->GetKeyRange("2", "3"), expected_list); + } +} + +TEST_P(KVStorageTest, GetHistory) { + { + std::vector > expected_list{}; + EXPECT_EQ(storage->GetHistory("1", 1, 5), expected_list); + } + { + std::vector > expected_list{ + std::make_pair("value3", 3), std::make_pair("value2", 2), + std::make_pair("value1", 1)}; + + EXPECT_EQ(storage->SetValueWithVersion("1", "value1", 0), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value2", 1), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value3", 2), 0); + + EXPECT_EQ(storage->GetHistory("1", 1, 5), expected_list); + } + + { + std::vector > expected_list{ + std::make_pair("value5", 5), std::make_pair("value4", 4), + std::make_pair("value3", 3), std::make_pair("value2", 2), + std::make_pair("value1", 1)}; + + EXPECT_EQ(storage->SetValueWithVersion("1", "value4", 3), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value5", 4), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value6", 5), 0); + EXPECT_EQ(storage->SetValueWithVersion("1", "value7", 6), 0); + + EXPECT_EQ(storage->GetHistory("1", 1, 5), expected_list); + } + + { + std::vector > expected_list{ + std::make_pair("value7", 7), std::make_pair("value6", 6)}; + + EXPECT_EQ(storage->GetTopHistory("1", 2), expected_list); + } +} + +INSTANTIATE_TEST_CASE_P(KVStorageTest, KVStorageTest, + ::testing::Values(MEM, LEVELDB)); + +} // namespace +} // namespace storage +} // namespace resdb diff --git a/chain/storage/leveldb.cpp b/chain/storage/leveldb.cpp new file mode 100644 index 000000000..2cc96fb59 --- /dev/null +++ b/chain/storage/leveldb.cpp @@ -0,0 +1,290 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "chain/storage/leveldb.h" + +#include + +#include "chain/storage/proto/kv.pb.h" + +namespace resdb { +namespace storage { + +std::unique_ptr NewResLevelDB(const std::string& path, + std::optional config) { + if (config == std::nullopt) { + config = LevelDBInfo(); + } + (*config).set_path(path); + return std::make_unique(config); +} + +std::unique_ptr NewResLevelDB(std::optional config) { + return std::make_unique(config); +} + +ResLevelDB::ResLevelDB(std::optional config) { + std::string path = "/tmp/nexres-leveldb"; + if (config.has_value()) { + write_buffer_size_ = (*config).write_buffer_size_mb() << 20; + write_batch_size_ = (*config).write_batch_size(); + if (!(*config).path().empty()) { + LOG(ERROR) << "Custom path for ResLevelDB provided in config: " + << (*config).path(); + path = (*config).path(); + } + } + CreateDB(path); +} + +void ResLevelDB::CreateDB(const std::string& path) { + LOG(ERROR) << "ResLevelDB Create DB: path:" << path + << " write buffer size:" << write_buffer_size_ + << " batch size:" << write_batch_size_; + leveldb::Options options; + options.create_if_missing = true; + options.write_buffer_size = write_buffer_size_; + + leveldb::DB* db = nullptr; + leveldb::Status status = leveldb::DB::Open(options, path, &db); + if (status.ok()) { + db_ = std::unique_ptr(db); + } + assert(status.ok()); + LOG(ERROR) << "Successfully opened LevelDB"; +} + +ResLevelDB::~ResLevelDB() { + if (db_) { + db_.reset(); + } +} + +int ResLevelDB::SetValue(const std::string& key, const std::string& value) { + batch_.Put(key, value); + + if (batch_.ApproximateSize() >= write_batch_size_) { + leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_); + if (status.ok()) { + batch_.Clear(); + return 0; + } else { + LOG(ERROR) << "flush buffer fail:" << status.ToString(); + return -1; + } + } + return 0; +} + +std::string ResLevelDB::GetValue(const std::string& key) { + std::string value = ""; + leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value); + if (status.ok()) { + return value; + } else { + return ""; + } +} + +std::string ResLevelDB::GetAllValues(void) { + std::string values = "["; + leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); + bool first_iteration = true; + for (it->SeekToFirst(); it->Valid(); it->Next()) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(it->value().ToString()); + } + values.append("]"); + + delete it; + return values; +} + +std::string ResLevelDB::GetRange(const std::string& min_key, + const std::string& max_key) { + std::string values = "["; + leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); + bool first_iteration = true; + for (it->Seek(min_key); it->Valid() && it->key().ToString() <= max_key; + it->Next()) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(it->value().ToString()); + } + values.append("]"); + + delete it; + return values; +} + +bool ResLevelDB::Flush() { + leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_); + if (status.ok()) { + batch_.Clear(); + return true; + } + LOG(ERROR) << "flush buffer fail:" << status.ToString(); + return false; +} + +int ResLevelDB::SetValueWithVersion(const std::string& key, + const std::string& value, int version) { + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return -2; + } + + int last_v = 0; + if (history.value_size() > 0) { + last_v = history.value(history.value_size() - 1).version(); + } + + if (last_v != version) { + LOG(ERROR) << "version does not match:" << version + << " old version:" << last_v; + return -2; + } + + Value* new_value = history.add_value(); + new_value->set_value(value); + new_value->set_version(version + 1); + + history.SerializeToString(&value_str); + return SetValue(key, value_str); +} + +std::pair ResLevelDB::GetValueWithVersion( + const std::string& key, int version) { + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return std::make_pair("", 0); + } + if (history.value_size() == 0) { + return std::make_pair("", 0); + } + if (version > 0) { + for (int i = history.value_size() - 1; i >= 0; --i) { + if (history.value(i).version() == version) { + return std::make_pair(history.value(i).value(), + history.value(i).version()); + } + if (history.value(i).version() < version) { + break; + } + } + } + int last_idx = history.value_size() - 1; + return std::make_pair(history.value(last_idx).value(), + history.value(last_idx).version()); +} + +// Return a map of > +std::map> ResLevelDB::GetAllItems() { + std::map> resp; + + leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); + for (it->SeekToFirst(); it->Valid(); it->Next()) { + ValueHistory history; + if (!history.ParseFromString(it->value().ToString()) || + history.value_size() == 0) { + LOG(ERROR) << "old_value parse fail"; + continue; + } + const Value& value = history.value(history.value_size() - 1); + resp.insert(std::make_pair(it->key().ToString(), + std::make_pair(value.value(), value.version()))); + } + delete it; + + return resp; +} + +std::map> ResLevelDB::GetKeyRange( + const std::string& min_key, const std::string& max_key) { + std::map> resp; + + leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); + for (it->Seek(min_key); it->Valid() && it->key().ToString() <= max_key; + it->Next()) { + ValueHistory history; + if (!history.ParseFromString(it->value().ToString()) || + history.value_size() == 0) { + LOG(ERROR) << "old_value parse fail"; + continue; + } + const Value& value = history.value(history.value_size() - 1); + resp.insert(std::make_pair(it->key().ToString(), + std::make_pair(value.value(), value.version()))); + } + delete it; + + return resp; +} + +// Return a list of +std::vector> ResLevelDB::GetHistory( + const std::string& key, int min_version, int max_version) { + std::vector> resp; + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return resp; + } + + for (int i = history.value_size() - 1; i >= 0; --i) { + if (history.value(i).version() < min_version) { + break; + } + if (history.value(i).version() <= max_version) { + resp.push_back( + std::make_pair(history.value(i).value(), history.value(i).version())); + } + } + + return resp; +} + +// Return a list of +std::vector> ResLevelDB::GetTopHistory( + const std::string& key, int top_number) { + std::vector> resp; + std::string value_str = GetValue(key); + ValueHistory history; + if (!history.ParseFromString(value_str)) { + LOG(ERROR) << "old_value parse fail"; + return resp; + } + + for (int i = history.value_size() - 1; + i >= 0 && resp.size() < static_cast(top_number); --i) { + resp.push_back( + std::make_pair(history.value(i).value(), history.value(i).version())); + } + + return resp; +} + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/leveldb.h b/chain/storage/leveldb.h new file mode 100644 index 000000000..199f1f274 --- /dev/null +++ b/chain/storage/leveldb.h @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include +#include +#include + +#include "chain/storage/proto/leveldb_config.pb.h" +#include "chain/storage/storage.h" +#include "leveldb/db.h" +#include "leveldb/write_batch.h" + +namespace resdb { +namespace storage { + +std::unique_ptr NewResLevelDB( + const std::string& path, std::optional config = std::nullopt); +std::unique_ptr NewResLevelDB( + std::optional config = std::nullopt); + +class ResLevelDB : public Storage { + public: + ResLevelDB(std::optional config_data = std::nullopt); + + virtual ~ResLevelDB(); + int SetValue(const std::string& key, const std::string& value) override; + std::string GetValue(const std::string& key) override; + std::string GetAllValues(void) override; + std::string GetRange(const std::string& min_key, + const std::string& max_key) override; + + int SetValueWithVersion(const std::string& key, const std::string& value, + int version) override; + std::pair GetValueWithVersion(const std::string& key, + int version) override; + + // Return a map of > + std::map> GetAllItems() override; + std::map> GetKeyRange( + const std::string& min_key, const std::string& max_key) override; + + // Return a list of + std::vector> GetHistory(const std::string& key, + int min_version, + int max_version) override; + + std::vector> GetTopHistory( + const std::string& key, int top_number) override; + + bool Flush() override; + + private: + void CreateDB(const std::string& path); + + private: + std::unique_ptr db_ = nullptr; + ::leveldb::WriteBatch batch_; + unsigned int write_buffer_size_ = 64 << 20; + unsigned int write_batch_size_ = 1; +}; + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/memory_db.cpp b/chain/storage/memory_db.cpp new file mode 100644 index 000000000..2d5b87258 --- /dev/null +++ b/chain/storage/memory_db.cpp @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "chain/storage/memory_db.h" + +#include + +namespace resdb { +namespace storage { + +std::unique_ptr NewMemoryDB() { return std::make_unique(); } + +MemoryDB::MemoryDB() {} + +int MemoryDB::SetValue(const std::string& key, const std::string& value) { + kv_map_[key] = value; + return 0; +} + +std::string MemoryDB::GetAllValues(void) { + std::string values = "["; + bool first_iteration = true; + for (auto kv : kv_map_) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(kv.second); + } + values.append("]"); + return values; +} + +std::string MemoryDB::GetRange(const std::string& min_key, + const std::string& max_key) { + std::string values = "["; + bool first_iteration = true; + for (auto kv : kv_map_) { + if (kv.first >= min_key && kv.first <= max_key) { + if (!first_iteration) values.append(","); + first_iteration = false; + values.append(kv.second); + } + } + values.append("]"); + return values; +} + +std::string MemoryDB::GetValue(const std::string& key) { + auto search = kv_map_.find(key); + if (search != kv_map_.end()) + return search->second; + else { + return ""; + } +} + +int MemoryDB::SetValueWithVersion(const std::string& key, + const std::string& value, int version) { + auto it = kv_map_with_v_.find(key); + if ((it == kv_map_with_v_.end() && version != 0) || + (it != kv_map_with_v_.end() && it->second.back().second != version)) { + LOG(ERROR) << " value version not match. key:" << key << " db version:" + << (it == kv_map_with_v_.end() ? 0 : it->second.back().second) + << " user version:" << version; + return -2; + } + kv_map_with_v_[key].push_back(std::make_pair(value, version + 1)); + return 0; +} + +std::pair MemoryDB::GetValueWithVersion( + const std::string& key, int version) { + auto search_it = kv_map_with_v_.find(key); + if (search_it != kv_map_with_v_.end() && search_it->second.size()) { + auto it = search_it->second.end(); + do { + --it; + if (it->second == version) { + return *it; + } + if (it->second < version) { + break; + } + } while (it != search_it->second.begin()); + it = --search_it->second.end(); + LOG(ERROR) << " key:" << key << " no version:" << version + << " return max:" << it->second; + return *it; + } + return std::make_pair("", 0); +} + +std::map> MemoryDB::GetAllItems() { + std::map> resp; + + for (const auto& it : kv_map_with_v_) { + resp.insert(std::make_pair(it.first, it.second.back())); + } + return resp; +} + +std::map> MemoryDB::GetKeyRange( + const std::string& min_key, const std::string& max_key) { + LOG(ERROR) << "min key:" << min_key << " max key:" << max_key; + std::map> resp; + for (const auto& it : kv_map_with_v_) { + if (it.first >= min_key && it.first <= max_key) { + resp.insert(std::make_pair(it.first, it.second.back())); + } + } + return resp; +} + +std::vector> MemoryDB::GetHistory( + const std::string& key, int min_version, int max_version) { + std::vector> resp; + auto search_it = kv_map_with_v_.find(key); + if (search_it == kv_map_with_v_.end()) { + return resp; + } + + auto it = search_it->second.end(); + do { + --it; + if (it->second < min_version) { + break; + } + if (it->second <= max_version) { + resp.push_back(*it); + } + } while (it != search_it->second.begin()); + return resp; +} + +std::vector> MemoryDB::GetTopHistory( + const std::string& key, int top_number) { + std::vector> resp; + auto search_it = kv_map_with_v_.find(key); + if (search_it == kv_map_with_v_.end()) { + return resp; + } + + auto it = search_it->second.end(); + do { + --it; + resp.push_back(*it); + if (resp.size() >= static_cast(top_number)) { + break; + } + } while (it != search_it->second.begin()); + return resp; +} + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/memory_db.h b/chain/storage/memory_db.h new file mode 100644 index 000000000..372f46474 --- /dev/null +++ b/chain/storage/memory_db.h @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include +#include +#include +#include + +#include "chain/storage/storage.h" + +namespace resdb { +namespace storage { + +// Key Value Storage supporting two types of interfaces: +// Non-version: +// It provides set and get function to set a value to a specific key +// Values will be set directly. +// Version: +// It provides set and get function to set a value to a specific key +// with a version. +// The version inside setting function is to support OCC verification. +// The version value should be obtained before setting +// and returned back when setting a new value. If the version is not +// the same as the old one, return failure. +// If the value of a specific version does not exist or providing +// version 0 as parameter when accessing get +// it returns the current value along its version. +// +// Note: Only one type of interface are allowed to be used. +// + +std::unique_ptr NewMemoryDB(); + +class MemoryDB : public Storage { + public: + MemoryDB(); + + int SetValue(const std::string& key, const std::string& value); + std::string GetValue(const std::string& key); + + std::string GetAllValues() override; + std::string GetRange(const std::string& min_key, + const std::string& max_key) override; + + int SetValueWithVersion(const std::string& key, const std::string& value, + int version) override; + std::pair GetValueWithVersion(const std::string& key, + int version) override; + + // Return a map of > + std::map> GetAllItems() override; + std::map> GetKeyRange( + const std::string& min_key, const std::string& max_key) override; + + // Return a list of + std::vector> GetHistory(const std::string& key, + int min_version, + int max_version) override; + + std::vector> GetTopHistory(const std::string& key, + int number) override; + + private: + std::unordered_map kv_map_; + std::unordered_map>> + kv_map_with_v_; +}; + +} // namespace storage +} // namespace resdb diff --git a/chain/storage/mock_storage.h b/chain/storage/mock_storage.h index 7aac187bf..963d92bbe 100644 --- a/chain/storage/mock_storage.h +++ b/chain/storage/mock_storage.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once @@ -38,6 +32,24 @@ class MockStorage : public Storage { MOCK_METHOD(std::string, GetAllValues, (), (override)); MOCK_METHOD(std::string, GetRange, (const std::string&, const std::string&), (override)); + + MOCK_METHOD(int, SetValueWithVersion, + (const std::string& key, const std::string& value, int version), + (override)); + + using ValueType = std::pair; + using ItemsType = std::map; + using ValuesType = std::vector; + + MOCK_METHOD(ValueType, GetValueWithVersion, + (const std::string& key, int version), (override)); + MOCK_METHOD(ItemsType, GetAllItems, (), (override)); + MOCK_METHOD(ItemsType, GetKeyRange, (const std::string&, const std::string&), + (override)); + MOCK_METHOD(ValuesType, GetHistory, (const std::string&, int, int), + (override)); + MOCK_METHOD(ValuesType, GetTopHistory, (const std::string&, int), (override)); + MOCK_METHOD(bool, Flush, (), (override)); }; diff --git a/chain/storage/proto/BUILD b/chain/storage/proto/BUILD new file mode 100644 index 000000000..0b1c7263f --- /dev/null +++ b/chain/storage/proto/BUILD @@ -0,0 +1,44 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +package(default_visibility = ["//visibility:public"]) + +load("@rules_cc//cc:defs.bzl", "cc_proto_library") +load("@rules_proto//proto:defs.bzl", "proto_library") + +proto_library( + name = "kv_proto", + srcs = ["kv.proto"], + visibility = ["//chain/storage:__subpackages__"], +) + +cc_proto_library( + name = "kv_cc_proto", + visibility = ["//chain/storage:__subpackages__"], + deps = [":kv_proto"], +) + +proto_library( + name = "leveldb_config_proto", + srcs = ["leveldb_config.proto"], +) + +cc_proto_library( + name = "leveldb_config_cc_proto", + deps = [":leveldb_config_proto"], +) diff --git a/chain/storage/proto/kv.proto b/chain/storage/proto/kv.proto new file mode 100644 index 000000000..8466b8dc7 --- /dev/null +++ b/chain/storage/proto/kv.proto @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +syntax = "proto3"; + +package resdb.storage; + +message Value { + bytes value = 1; + int32 version = 2; +} + +message ValueHistory { + repeated Value value = 1; +} + diff --git a/chain/storage/proto/leveldb_config.proto b/chain/storage/proto/leveldb_config.proto new file mode 100644 index 000000000..d8be25195 --- /dev/null +++ b/chain/storage/proto/leveldb_config.proto @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +syntax = "proto3"; + +package resdb.storage; + +message LevelDBInfo { + uint32 write_buffer_size_mb = 2; + uint32 write_batch_size = 3; + string path = 4; +} diff --git a/chain/storage/res_leveldb.cpp b/chain/storage/res_leveldb.cpp deleted file mode 100644 index 0cd48ccae..000000000 --- a/chain/storage/res_leveldb.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "chain/storage/res_leveldb.h" - -#include - -namespace resdb { - -std::unique_ptr NewResLevelDB(const char* cert_file, - resdb::ResConfigData config_data) { - return std::make_unique(cert_file, config_data); -} - -ResLevelDB::ResLevelDB(const char* cert_file, - std::optional config_data) { - std::string directory_id = ""; - - std::string path = "/tmp/nexres-leveldb"; - if (cert_file == NULL) { - LOG(ERROR) << "No cert file provided"; - } else { - LOG(ERROR) << "Cert file: " << cert_file; - std::string str(cert_file); - - for (int i = 0; i < (int)str.size(); i++) { - if (str[i] >= '0' && str[i] <= '9') { - directory_id += std::string(1, cert_file[i]); - } - } - - if (directory_id == "") { - directory_id = "0"; - } - } - - if (config_data.has_value()) { - LevelDBInfo config = (*config_data).leveldb_info(); - write_buffer_size_ = config.write_buffer_size_mb() << 20; - write_batch_size_ = config.write_batch_size(); - if (config.path() != "") { - LOG(ERROR) << "Custom path for ResLevelDB provided in config: " - << config.path(); - path = config.path(); - } - if (config.generate_unique_pathnames()) { - LOG(ERROR) << "Adding number to generate unique pathname: " - << directory_id; - path += directory_id; - } - } - CreateDB(path); -} - -void ResLevelDB::CreateDB(const std::string& path) { - LOG(ERROR) << "ResLevelDB Create DB: path:" << path - << " write buffer size:" << write_buffer_size_ - << " batch size:" << write_batch_size_; - leveldb::Options options; - options.create_if_missing = true; - options.write_buffer_size = write_buffer_size_; - - leveldb::DB* db = nullptr; - leveldb::Status status = leveldb::DB::Open(options, path, &db); - if (status.ok()) { - db_ = std::unique_ptr(db); - } - assert(status.ok()); - LOG(ERROR) << "Successfully opened LevelDB"; -} - -ResLevelDB::~ResLevelDB() { - if (db_) { - db_.reset(); - } -} - -int ResLevelDB::SetValue(const std::string& key, const std::string& value) { - batch_.Put(key, value); - - if (batch_.ApproximateSize() >= write_batch_size_) { - leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_); - if (status.ok()) { - batch_.Clear(); - return 0; - } else { - LOG(ERROR) << "flush buffer fail:" << status.ToString(); - return -1; - } - } - return 0; -} - -std::string ResLevelDB::GetValue(const std::string& key) { - std::string value = ""; - leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value); - if (status.ok()) { - return value; - } else { - LOG(ERROR) << "get value fail:" << status.ToString(); - return ""; - } -} - -std::string ResLevelDB::GetAllValues(void) { - std::string values = "["; - leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); - bool first_iteration = true; - for (it->SeekToFirst(); it->Valid(); it->Next()) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(it->value().ToString()); - } - values.append("]"); - - delete it; - return values; -} - -std::string ResLevelDB::GetRange(const std::string& min_key, - const std::string& max_key) { - std::string values = "["; - leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); - bool first_iteration = true; - for (it->Seek(min_key); it->Valid() && it->key().ToString() <= max_key; - it->Next()) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(it->value().ToString()); - } - values.append("]"); - - delete it; - return values; -} - -bool ResLevelDB::Flush() { - leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_); - if (status.ok()) { - batch_.Clear(); - return true; - } - LOG(ERROR) << "flush buffer fail:" << status.ToString(); - return false; -} - -} // namespace resdb diff --git a/chain/storage/res_leveldb.h b/chain/storage/res_leveldb.h deleted file mode 100644 index f2c526319..000000000 --- a/chain/storage/res_leveldb.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#pragma once - -#include -#include -#include - -#include "chain/storage/storage.h" -#include "leveldb/db.h" -#include "leveldb/write_batch.h" -#include "platform/proto/replica_info.pb.h" - -namespace resdb { - -std::unique_ptr NewResLevelDB(const char* cert_file, - resdb::ResConfigData config_data); - -class ResLevelDB : public Storage { - public: - ResLevelDB(const char* cert_file, std::optional config_data); - - virtual ~ResLevelDB(); - int SetValue(const std::string& key, const std::string& value) override; - std::string GetValue(const std::string& key) override; - std::string GetAllValues(void) override; - std::string GetRange(const std::string& min_key, - const std::string& max_key) override; - - bool Flush() override; - - private: - void CreateDB(const std::string& path); - - private: - std::unique_ptr db_ = nullptr; - ::leveldb::WriteBatch batch_; - unsigned int write_buffer_size_ = 64 << 20; - unsigned int write_batch_size_ = 1; -}; - -} // namespace resdb diff --git a/chain/storage/res_leveldb_test.cpp b/chain/storage/res_leveldb_test.cpp deleted file mode 100644 index 17deddffd..000000000 --- a/chain/storage/res_leveldb_test.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "chain/storage/res_leveldb.h" - -#include -#include -#include - -#include - -namespace resdb { - -namespace { - -using ::testing::Test; - -class ResLevelDBDurableTest : public Test { - public: - ResLevelDBDurableTest() { Reset(); } - ~ResLevelDBDurableTest() {} - int Set(const std::string& key, const std::string& value) { - resdb::ResConfigData config_data; - config_data.mutable_leveldb_info()->set_path(path_); - return NewResLevelDB(NULL, config_data)->SetValue(key, value); - } - - std::string Get(const std::string& key) { - resdb::ResConfigData config_data; - config_data.mutable_leveldb_info()->set_path(path_); - return NewResLevelDB(NULL, config_data)->GetValue(key); - } - - std::string GetAllValues() { - resdb::ResConfigData config_data; - config_data.mutable_leveldb_info()->set_path(path_); - return NewResLevelDB(NULL, config_data)->GetAllValues(); - } - - std::string GetRange(const std::string& min_key, const std::string& max_key) { - resdb::ResConfigData config_data; - config_data.mutable_leveldb_info()->set_path(path_); - return NewResLevelDB(NULL, config_data)->GetRange(min_key, max_key); - } - - void Reset() { std::filesystem::remove_all(path_.c_str()); } - - private: - std::string path_ = "/tmp/leveldb_test"; -}; - -TEST_F(ResLevelDBDurableTest, GetEmptyValue) { - EXPECT_EQ(Get("empty_key"), ""); -} - -TEST_F(ResLevelDBDurableTest, SetValue) { - EXPECT_EQ(Set("test_key", "test_value"), 0); -} - -TEST_F(ResLevelDBDurableTest, GetValue) { - EXPECT_EQ(Set("test_key", "test_value"), 0); - EXPECT_EQ(Get("test_key"), "test_value"); -} - -TEST_F(ResLevelDBDurableTest, SetNewValue) { - EXPECT_EQ(Set("test_key", "new_value"), 0); -} - -TEST_F(ResLevelDBDurableTest, GetNewValue) { EXPECT_EQ(Get("test_key"), ""); } - -TEST_F(ResLevelDBDurableTest, GetAllValues) { - EXPECT_EQ(Set("a", "a"), 0); - EXPECT_EQ(Set("b", "b"), 0); - EXPECT_EQ(Set("c", "c"), 0); - EXPECT_EQ(GetAllValues(), "[a,b,c]"); -} - -TEST_F(ResLevelDBDurableTest, GetRange) { - EXPECT_EQ(Set("key1", "value1"), 0); - EXPECT_EQ(Set("key2", "value2"), 0); - EXPECT_EQ(Set("key3", "value3"), 0); - EXPECT_EQ(GetRange("key1", "key3"), "[value1,value2,value3]"); - EXPECT_EQ(GetRange("key1", "key2"), "[value1,value2]"); - EXPECT_EQ(GetRange("key4", "key5"), "[]"); -} - -} // namespace - -} // namespace resdb diff --git a/chain/storage/res_rocksdb.cpp b/chain/storage/res_rocksdb.cpp deleted file mode 100644 index 2655aca2a..000000000 --- a/chain/storage/res_rocksdb.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "chain/storage/res_rocksdb.h" - -#include -#include - -namespace resdb { - -std::unique_ptr NewResRocksDB( - const char* cert_file, std::optional config_data) { - return std::make_unique(cert_file, config_data); -} - -ResRocksDB::ResRocksDB(const char* cert_file, - std::optional config_data) { - std::string directory_id = ""; - - std::string path = "/tmp/nexres-rocksdb"; - LOG(ERROR) << "Default database path: " << path; - - if (cert_file == NULL) { - LOG(ERROR) << "No cert file provided"; - } else { - LOG(ERROR) << "Cert file: " << cert_file; - std::string str(cert_file); - - for (int i = 0; i < (int)str.size(); i++) { - if (str[i] >= '0' && str[i] <= '9') { - directory_id += std::string(1, cert_file[i]); - } - } - - if (directory_id == "") { - directory_id = "0"; - } - } - - if (config_data.has_value()) { - RocksDBInfo config = (*config_data).rocksdb_info(); - num_threads_ = config.num_threads(); - write_buffer_size_ = config.write_buffer_size_mb() << 20; - write_batch_size_ = config.write_batch_size(); - if (config.path() != "") { - LOG(ERROR) << "Custom path for RocksDB provided in config: " - << config.path(); - path = config.path(); - } - if (config.generate_unique_pathnames()) { - LOG(ERROR) << "Adding number to generate unique pathname: " - << directory_id; - path += directory_id; - } - } - LOG(ERROR) << "RocksDB Settings: " << num_threads_ << " " - << write_buffer_size_ << " " << write_batch_size_; - - rocksdb::Options options; - options.create_if_missing = true; - if (num_threads_ > 1) options.IncreaseParallelism(num_threads_); - options.OptimizeLevelStyleCompaction(); - options.write_buffer_size = write_buffer_size_; - - rocksdb::DB* db = nullptr; - rocksdb::Status status = rocksdb::DB::Open(options, path, &db); - if (status.ok()) { - db_ = std::unique_ptr(db); - LOG(ERROR) << "Successfully opened RocksDB in path: " << path; - } else { - LOG(ERROR) << "RocksDB status fail"; - } - assert(status.ok()); -} - -ResRocksDB::~ResRocksDB() { - if (db_) { - db_.reset(); - } -} - -int ResRocksDB::SetValue(const std::string& key, const std::string& value) { - batch_.Put(key, value); - - if (batch_.Count() >= write_batch_size_) { - rocksdb::Status status = db_->Write(rocksdb::WriteOptions(), &batch_); - if (status.ok()) { - batch_.Clear(); - } else { - LOG(ERROR) << "write value fail:" << status.ToString(); - return -1; - } - } - return 0; -} - -std::string ResRocksDB::GetValue(const std::string& key) { - std::string value = ""; - rocksdb::Status status = db_->Get(rocksdb::ReadOptions(), key, &value); - if (status.ok()) { - return value; - } else { - return ""; - } -} - -std::string ResRocksDB::GetAllValues(void) { - std::string values = "["; - rocksdb::Iterator* itr = db_->NewIterator(rocksdb::ReadOptions()); - bool first_iteration = true; - for (itr->SeekToFirst(); itr->Valid(); itr->Next()) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(itr->value().ToString()); - } - values.append("]"); - - delete itr; - return values; -} - -std::string ResRocksDB::GetRange(const std::string& min_key, - const std::string& max_key) { - std::string values = "["; - rocksdb::Iterator* itr = db_->NewIterator(rocksdb::ReadOptions()); - bool first_iteration = true; - for (itr->Seek(min_key); itr->Valid() && itr->key().ToString() <= max_key; - itr->Next()) { - if (!first_iteration) values.append(","); - first_iteration = false; - values.append(itr->value().ToString()); - } - values.append("]"); - - delete itr; - return values; -} - -bool ResRocksDB::Flush() { - rocksdb::Status status = db_->Write(rocksdb::WriteOptions(), &batch_); - if (status.ok()) { - batch_.Clear(); - return true; - } - LOG(ERROR) << "write value fail:" << status.ToString(); - return false; -} - -} // namespace resdb diff --git a/chain/storage/res_rocksdb.h b/chain/storage/res_rocksdb.h deleted file mode 100644 index 706957c2f..000000000 --- a/chain/storage/res_rocksdb.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#pragma once - -#include -#include - -#include "chain/storage/storage.h" -#include "platform/proto/replica_info.pb.h" -#include "rocksdb/db.h" -#include "rocksdb/write_batch.h" - -namespace resdb { - -std::unique_ptr NewResRocksDB( - const char* cert_file, std::optional config_data); - -class ResRocksDB : public Storage { - public: - ResRocksDB(const char* cert_file, std::optional config_data); - virtual ~ResRocksDB(); - int SetValue(const std::string& key, const std::string& value) override; - std::string GetValue(const std::string& key) override; - std::string GetAllValues(void) override; - std::string GetRange(const std::string& min_key, - const std::string& max_key) override; - - bool Flush() override; - - private: - std::unique_ptr db_ = nullptr; - rocksdb::WriteBatch batch_; - unsigned int num_threads_ = 1; - unsigned int write_buffer_size_ = 64 << 20; - unsigned int write_batch_size_ = 1; -}; - -} // namespace resdb diff --git a/chain/storage/res_rocksdb_test.cpp b/chain/storage/res_rocksdb_test.cpp deleted file mode 100644 index 5c17f8b7f..000000000 --- a/chain/storage/res_rocksdb_test.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "storage/res_rocksdb.h" - -#include -#include - -#include - -namespace resdb { -namespace { - -using ::testing::Test; - -class RocksDBDurableTest : public Test { - public: - RocksDBDurableTest() { Reset(); } - - int Set(const std::string& key, const std::string& value) { - ResConfigData config_data; - config_data.mutable_rocksdb_info()->set_path(path_); - return NewResRocksDB(NULL, config_data)->SetValue(key, value); - } - - std::string Get(const std::string& key) { - ResConfigData config_data; - config_data.mutable_rocksdb_info()->set_path(path_); - return NewResRocksDB(NULL, config_data)->GetValue(key); - } - - std::string GetAllValues() { - ResConfigData config_data; - config_data.mutable_rocksdb_info()->set_path(path_); - return NewResRocksDB(NULL, config_data)->GetAllValues(); - } - - std::string GetRange(const std::string& min_key, const std::string& max_key) { - ResConfigData config_data; - config_data.mutable_rocksdb_info()->set_path(path_); - return NewResRocksDB(NULL, config_data)->GetRange(min_key, max_key); - } - - void Reset() { std::filesystem::remove_all(path_.c_str()); } - - private: - std::string path_ = "/tmp/rocksdb_test"; -}; - -TEST_F(RocksDBDurableTest, GetEmptyValue) { EXPECT_EQ(Get("empty_key"), ""); } - -TEST_F(RocksDBDurableTest, SetValue) { - EXPECT_EQ(Set("test_key", "test_value"), 0); -} - -TEST_F(RocksDBDurableTest, GetValue) { - EXPECT_EQ(Set("test_key", "test_value"), 0); - EXPECT_EQ(Get("test_key"), "test_value"); -} - -TEST_F(RocksDBDurableTest, SetNewValue) { - EXPECT_EQ(Set("test_key", "new_value"), 0); -} - -TEST_F(RocksDBDurableTest, GetNewValue) { - EXPECT_EQ(Set("test_key", "new_value1"), 0); - EXPECT_EQ(Get("test_key"), "new_value1"); -} - -TEST_F(RocksDBDurableTest, GetAllValues) { - EXPECT_EQ(Set("a", "a"), 0); - EXPECT_EQ(Set("b", "b"), 0); - EXPECT_EQ(Set("c", "c"), 0); - EXPECT_EQ(GetAllValues(), "[a,b,c]"); -} - -TEST_F(RocksDBDurableTest, GetRange) { - EXPECT_EQ(Set("key1", "value1"), 0); - EXPECT_EQ(Set("key2", "value2"), 0); - EXPECT_EQ(Set("key3", "value3"), 0); - EXPECT_EQ(GetRange("key1", "key3"), "[value1,value2,value3]"); - EXPECT_EQ(GetRange("key1", "key2"), "[value1,value2]"); - EXPECT_EQ(GetRange("key4", "key5"), "[]"); -} - -} // namespace -} // namespace resdb diff --git a/chain/storage/setting/BUILD b/chain/storage/setting/BUILD new file mode 100644 index 000000000..25d11b4e8 --- /dev/null +++ b/chain/storage/setting/BUILD @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +package(default_visibility = ["//visibility:public"]) + +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") + +bool_flag( + name = "enable_leveldb", + build_setting_default = False, + visibility = ["//visibility:public"], +) + +config_setting( + name = "enable_leveldb_setting", + values = { + "define": "enable_leveldb=True", + }, + visibility = ["//visibility:public"], +) diff --git a/chain/storage/storage.h b/chain/storage/storage.h index 3ab095682..76e352de8 100644 --- a/chain/storage/storage.h +++ b/chain/storage/storage.h @@ -1,31 +1,27 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once +#include #include +#include namespace resdb { @@ -34,22 +30,31 @@ class Storage { Storage() = default; virtual ~Storage() = default; - // Set value by key - // Return >=0 if success. virtual int SetValue(const std::string& key, const std::string& value) = 0; - - // Get value by key virtual std::string GetValue(const std::string& key) = 0; - - // Get all values in db virtual std::string GetAllValues() = 0; - - // Get values on a range of keys virtual std::string GetRange(const std::string& min_key, const std::string& max_key) = 0; - // Flush data to disk - virtual bool Flush() = 0; + virtual int SetValueWithVersion(const std::string& key, + const std::string& value, int version) = 0; + virtual std::pair GetValueWithVersion( + const std::string& key, int version) = 0; + + // Return a map of > + virtual std::map> GetAllItems() = 0; + virtual std::map> GetKeyRange( + const std::string& min_key, const std::string& max_key) = 0; + + // Return a list of from a key + // The version list is sorted by the version value in descending order + virtual std::vector> GetHistory( + const std::string& key, int min_version, int max_version) = 0; + + virtual std::vector> GetTopHistory( + const std::string& key, int number) = 0; + + virtual bool Flush() { return true; }; }; } // namespace resdb diff --git a/chain/storage/txn_memory_db.cpp b/chain/storage/txn_memory_db.cpp deleted file mode 100644 index f16445c0e..000000000 --- a/chain/storage/txn_memory_db.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "chain/storage/txn_memory_db.h" - -#include - -namespace resdb { - -TxnMemoryDB::TxnMemoryDB() : max_seq_(0) {} - -Request* TxnMemoryDB::Get(uint64_t seq) { - std::unique_lock lk(mutex_); - if (data_.find(seq) == data_.end()) { - return nullptr; - } - return data_[seq].get(); -} - -void TxnMemoryDB::Put(std::unique_ptr request) { - std::unique_lock lk(mutex_); - max_seq_ = request->seq(); - data_[max_seq_] = std::move(request); -} - -uint64_t TxnMemoryDB::GetMaxSeq() { return max_seq_; } - -} // namespace resdb diff --git a/chain/storage/txn_memory_db.h b/chain/storage/txn_memory_db.h deleted file mode 100644 index de69d70cb..000000000 --- a/chain/storage/txn_memory_db.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#pragma once - -#include -#include - -#include "platform/proto/resdb.pb.h" - -namespace resdb { - -class TxnMemoryDB { - public: - TxnMemoryDB(); - Request* Get(uint64_t seq); - void Put(std::unique_ptr request); - uint64_t GetMaxSeq(); - - private: - std::mutex mutex_; - std::unordered_map > data_; - std::atomic max_seq_; -}; - -} // namespace resdb diff --git a/chain/storage/txn_memory_db_test.cpp b/chain/storage/txn_memory_db_test.cpp deleted file mode 100644 index 1ff726dcd..000000000 --- a/chain/storage/txn_memory_db_test.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2019-2022 ExpoLab, UC Davis - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "database/txn_memory_db.h" - -#include -#include - -#include "common/test/test_macros.h" - -namespace resdb { -namespace { - -using ::resdb::testing::EqualsProto; -using ::testing::Pointee; - -TEST(TxnMemoryDBTest, GetEmptyValue) { - TxnMemoryDB db; - EXPECT_EQ(db.Get(1), nullptr); -} - -TEST(TxnMemoryDBTest, GetValue) { - Request request; - request.set_seq(1); - request.set_data("test"); - - TxnMemoryDB db; - db.Put(std::make_unique(request)); - EXPECT_THAT(db.Get(1), Pointee(EqualsProto(request))); -} - -TEST(TxnMemoryDBTest, GetSecondValue) { - Request request; - request.set_seq(1); - request.set_data("test"); - - TxnMemoryDB db; - db.Put(std::make_unique(request)); - - request.set_seq(1); - request.set_data("test_1"); - db.Put(std::make_unique(request)); - - EXPECT_THAT(db.Get(1), Pointee(EqualsProto(request))); -} - -} // namespace - -} // namespace resdb diff --git a/common/BUILD b/common/BUILD index 62d32413c..c5982dd14 100644 --- a/common/BUILD +++ b/common/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( @@ -15,6 +33,13 @@ cc_library( ], ) +cc_library( + name = "beast", + deps = [ + "@boost//:beast", + ], +) + cc_library( name = "boost_lockfree", deps = [ diff --git a/common/crypto/BUILD b/common/crypto/BUILD index 1b7dbebe1..e55969031 100644 --- a/common/crypto/BUILD +++ b/common/crypto/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/common/crypto/hash.cpp b/common/crypto/hash.cpp index 8173109d0..b96a2b81d 100644 --- a/common/crypto/hash.cpp +++ b/common/crypto/hash.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "common/crypto/hash.h" diff --git a/common/crypto/hash.h b/common/crypto/hash.h index 10d028cba..5136bfd55 100644 --- a/common/crypto/hash.h +++ b/common/crypto/hash.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/common/crypto/hash_test.cpp b/common/crypto/hash_test.cpp index 258d4a645..8cb32022c 100644 --- a/common/crypto/hash_test.cpp +++ b/common/crypto/hash_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "common/crypto/hash.h" diff --git a/common/crypto/key_generator.cpp b/common/crypto/key_generator.cpp index 89ec69715..5a60923fd 100644 --- a/common/crypto/key_generator.cpp +++ b/common/crypto/key_generator.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "common/crypto/key_generator.h" diff --git a/common/crypto/key_generator.h b/common/crypto/key_generator.h index 846039ff5..fcbe0f59e 100644 --- a/common/crypto/key_generator.h +++ b/common/crypto/key_generator.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/common/crypto/mock_signature_verifier.h b/common/crypto/mock_signature_verifier.h index 1bf88628d..e22d3586c 100644 --- a/common/crypto/mock_signature_verifier.h +++ b/common/crypto/mock_signature_verifier.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/common/crypto/signature_utils.cpp b/common/crypto/signature_utils.cpp index e86f99b1c..4df11022b 100644 --- a/common/crypto/signature_utils.cpp +++ b/common/crypto/signature_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "common/crypto/signature_utils.h" diff --git a/common/crypto/signature_utils.h b/common/crypto/signature_utils.h index 18415eaa4..927cbbd38 100644 --- a/common/crypto/signature_utils.h +++ b/common/crypto/signature_utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/common/crypto/signature_verifier.cpp b/common/crypto/signature_verifier.cpp index 09e819853..cf2046e25 100644 --- a/common/crypto/signature_verifier.cpp +++ b/common/crypto/signature_verifier.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "common/crypto/signature_verifier.h" diff --git a/common/crypto/signature_verifier.h b/common/crypto/signature_verifier.h index 619908ea2..2a8e312cd 100644 --- a/common/crypto/signature_verifier.h +++ b/common/crypto/signature_verifier.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/common/crypto/signature_verifier_interface.cpp b/common/crypto/signature_verifier_interface.cpp index 07bed5cca..865eccffc 100644 --- a/common/crypto/signature_verifier_interface.cpp +++ b/common/crypto/signature_verifier_interface.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "common/crypto/signature_verifier_interface.h" diff --git a/common/crypto/signature_verifier_interface.h b/common/crypto/signature_verifier_interface.h index eea1b410d..197387fc3 100644 --- a/common/crypto/signature_verifier_interface.h +++ b/common/crypto/signature_verifier_interface.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/common/crypto/signature_verifier_test.cpp b/common/crypto/signature_verifier_test.cpp index b7453bb92..3bdecc8da 100644 --- a/common/crypto/signature_verifier_test.cpp +++ b/common/crypto/signature_verifier_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "common/crypto/signature_verifier.h" diff --git a/common/proto/BUILD b/common/proto/BUILD index d6647a535..2122cef4b 100644 --- a/common/proto/BUILD +++ b/common/proto/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) load("@rules_cc//cc:defs.bzl", "cc_proto_library") diff --git a/common/proto/signature_info.proto b/common/proto/signature_info.proto index 607fe4ac7..cc1cfc425 100644 --- a/common/proto/signature_info.proto +++ b/common/proto/signature_info.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb; diff --git a/common/test/BUILD b/common/test/BUILD index df156e5c3..e6bd3d615 100644 --- a/common/test/BUILD +++ b/common/test/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/common/test/json_test.cpp b/common/test/json_test.cpp index ccc286800..4fcaeed50 100644 --- a/common/test/json_test.cpp +++ b/common/test/json_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/common/test/test.proto b/common/test/test.proto index c8a075d1e..2e8320c00 100644 --- a/common/test/test.proto +++ b/common/test/test.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb.test; diff --git a/common/test/test_macros.h b/common/test/test_macros.h index 6a991ed46..5e510f2a2 100644 --- a/common/test/test_macros.h +++ b/common/test/test_macros.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/common/utils/BUILD b/common/utils/BUILD index 3f6d1d060..44d5e69b3 100644 --- a/common/utils/BUILD +++ b/common/utils/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/common/utils/utils.cpp b/common/utils/utils.cpp index d4707fc5e..c51241204 100644 --- a/common/utils/utils.cpp +++ b/common/utils/utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "common/utils/utils.h" diff --git a/common/utils/utils.h b/common/utils/utils.h index bc57af07d..2a17286a8 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/dev/.rat-excludes b/dev/.rat-excludes new file mode 100644 index 000000000..7889a072b --- /dev/null +++ b/dev/.rat-excludes @@ -0,0 +1,19 @@ +.bazelrc +.bazelversion +.clang-format +.licenserc.yaml +repositories.bzl +.gitignore +.git +.rat-excludes +DISCLAIMER-WIP +CNAME +WORKSPACE +build +.*\.conf +.*\.config +.*\.pub +.*\.pri +Doxyfile +header +.*\.sol diff --git a/dev/check-license b/dev/check-license new file mode 100755 index 000000000..e929e68bf --- /dev/null +++ b/dev/check-license @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +acquire_rat_jar () { + + URL="https://repo.maven.apache.org/maven2/org/apache/rat/apache-rat/${RAT_VERSION}/apache-rat-${RAT_VERSION}.jar" + + JAR="$rat_jar" + + # Download rat launch jar if it hasn't been downloaded yet + if [ ! -f "$JAR" ]; then + # Download + printf "Attempting to fetch rat\n" + JAR_DL="${JAR}.part" + if [ $(command -v curl) ]; then + curl -L --silent "${URL}" > "$JAR_DL" && mv "$JAR_DL" "$JAR" + elif [ $(command -v wget) ]; then + wget --quiet ${URL} -O "$JAR_DL" && mv "$JAR_DL" "$JAR" + else + printf "You do not have curl or wget installed, please install rat manually.\n" + exit -1 + fi + fi + + unzip -tq "$JAR" &> /dev/null + if [ $? -ne 0 ]; then + # We failed to download + rm "$JAR" + printf "Our attempt to download rat locally to ${JAR} failed. Please install rat manually.\n" + exit -1 + fi +} + +# Go to the Spark project root directory +FWDIR="$(cd "`dirname "$0"`"/..; pwd)" +cd "$FWDIR" + +if test -x "$JAVA_HOME/bin/java"; then + declare java_cmd="$JAVA_HOME/bin/java" +else + declare java_cmd=java +fi + +export RAT_VERSION=0.16.1 +export rat_jar="$FWDIR"/lib/apache-rat-${RAT_VERSION}.jar +mkdir -p "$FWDIR"/lib + +[[ -f "$rat_jar" ]] || acquire_rat_jar || { + echo "Download failed. Obtain the rat jar manually and place it at $rat_jar" + exit 1 +} + +mkdir -p build +$java_cmd -jar "$rat_jar" --scan-hidden-directories -E "$FWDIR"/dev/.rat-excludes -d "$FWDIR" > build/rat-results.txt + +if [ $? -ne 0 ]; then + echo "RAT exited abnormally" + exit 1 +fi + +ERRORS="$(cat build/rat-results.txt | grep -e "??")" + +if test ! -z "$ERRORS"; then + echo "Could not find Apache license headers in the following files:" + echo "$ERRORS" + exit 1 +else + echo -e "RAT checks passed." +fi diff --git a/documents/doxygen/Doxyfile b/documents/doxygen/Doxyfile index 547a34fcd..13911062c 100644 --- a/documents/doxygen/Doxyfile +++ b/documents/doxygen/Doxyfile @@ -42,7 +42,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = ResilientDB +PROJECT_NAME = ResilientDB # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -54,7 +54,7 @@ PROJECT_NUMBER = v1.3.1 # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = NexRes +PROJECT_BRIEF = ResilientDB # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 @@ -1330,7 +1330,7 @@ HTML_FILE_EXTENSION = .html # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_HEADER = +HTML_HEADER = header # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard @@ -1370,7 +1370,7 @@ HTML_STYLESHEET = # documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = +HTML_EXTRA_STYLESHEET = doxygen_html_style.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note diff --git a/documents/doxygen/DoxygenLayout.xml b/documents/doxygen/DoxygenLayout.xml index 34a428d5c..50f95acc5 100644 --- a/documents/doxygen/DoxygenLayout.xml +++ b/documents/doxygen/DoxygenLayout.xml @@ -1,3 +1,19 @@ + diff --git a/documents/doxygen/doxygen_html_style.css b/documents/doxygen/doxygen_html_style.css new file mode 100644 index 000000000..93cbf2e14 --- /dev/null +++ b/documents/doxygen/doxygen_html_style.css @@ -0,0 +1,20 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +img[src="logo.png"]{ + width: 250px; + height: 83px; +} diff --git a/documents/doxygen/header b/documents/doxygen/header new file mode 100644 index 000000000..7fd1bd266 --- /dev/null +++ b/documents/doxygen/header @@ -0,0 +1,60 @@ + + + + + + + + +$projectname: $title +$title + + + + + + + + +$treeview +$search +$mathjax +$darkmode + +$extrastylesheet + + + + +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + +
$searchbox
$searchbox
+
+ + diff --git a/documents/doxygen/logo.png b/documents/doxygen/logo.png index 58dd20081318fcd948611295d8a7cb44f0c17b3a..b9509d2e9b0f6536d8223e3518e2aff72715eb19 100644 GIT binary patch literal 71672 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 Ux`XEa!1!YDboFyt=akR{0EmETS^xk5 diff --git a/documents/file/prometheus.yml b/documents/file/prometheus.yml index 72fbeaf50..e2204277a 100644 --- a/documents/file/prometheus.yml +++ b/documents/file/prometheus.yml @@ -1,7 +1,26 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + # my global config global: - scrape_interval: 5s # Set the scrape interval to every 15 seconds. Default is every 1 minute. - evaluation_interval: 5s # Evaluate rules every 15 seconds. The default is every 1 minute. + scrape_interval: 5s # Set the scrape interval to every 5 seconds. Default is every 1 minute. + evaluation_interval: 5s # Evaluate rules every 5 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). # Alertmanager configuration diff --git a/entrypoint.sh b/entrypoint.sh index a5ef6599c..0b3d1019f 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,4 +1,21 @@ -#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ./service/tools/kv/server_tools/start_kv_service.sh -tail -f /dev/null \ No newline at end of file +tail -f /dev/null diff --git a/executor/common/BUILD b/executor/common/BUILD index 0e0d8ee5a..e50dab38b 100644 --- a/executor/common/BUILD +++ b/executor/common/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/executor/common/custom_query.h b/executor/common/custom_query.h index e574a98dd..2c8bf4a7a 100644 --- a/executor/common/custom_query.h +++ b/executor/common/custom_query.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/common/mock_transaction_manager.h b/executor/common/mock_transaction_manager.h index 86972f662..b4a6ba532 100644 --- a/executor/common/mock_transaction_manager.h +++ b/executor/common/mock_transaction_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/common/transaction_manager.cpp b/executor/common/transaction_manager.cpp index 854715863..036f9619d 100644 --- a/executor/common/transaction_manager.cpp +++ b/executor/common/transaction_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/common/transaction_manager.h" diff --git a/executor/common/transaction_manager.h b/executor/common/transaction_manager.h index 7e243f97a..16e1a58d5 100644 --- a/executor/common/transaction_manager.h +++ b/executor/common/transaction_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/contract/executor/BUILD b/executor/contract/executor/BUILD index d93b372b4..c6e40c657 100644 --- a/executor/contract/executor/BUILD +++ b/executor/contract/executor/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/executor/contract/executor/contract_executor.cpp b/executor/contract/executor/contract_executor.cpp index 6e8c994a0..6db35ad71 100644 --- a/executor/contract/executor/contract_executor.cpp +++ b/executor/contract/executor/contract_executor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/contract/executor/contract_executor.h" diff --git a/executor/contract/executor/contract_executor.h b/executor/contract/executor/contract_executor.h index 8c2a50c80..c902e2977 100644 --- a/executor/contract/executor/contract_executor.h +++ b/executor/contract/executor/contract_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/contract/executor/contract_executor_test.cpp b/executor/contract/executor/contract_executor_test.cpp index 5d29333dd..b8b63aec5 100644 --- a/executor/contract/executor/contract_executor_test.cpp +++ b/executor/contract/executor/contract_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/contract/executor/contract_executor.h" diff --git a/executor/contract/executor/test_data/BUILD b/executor/contract/executor/test_data/BUILD index 65e3dc3d9..252132954 100644 --- a/executor/contract/executor/test_data/BUILD +++ b/executor/contract/executor/test_data/BUILD @@ -1 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + exports_files(["contract.json"]) diff --git a/executor/contract/manager/BUILD b/executor/contract/manager/BUILD index 17d9d709b..f1d26925e 100644 --- a/executor/contract/manager/BUILD +++ b/executor/contract/manager/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/executor/contract/manager/address_manager.cpp b/executor/contract/manager/address_manager.cpp index e155d9f83..2a886dac5 100644 --- a/executor/contract/manager/address_manager.cpp +++ b/executor/contract/manager/address_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/contract/manager/address_manager.h" diff --git a/executor/contract/manager/address_manager.h b/executor/contract/manager/address_manager.h index b0446503c..4e6055aad 100644 --- a/executor/contract/manager/address_manager.h +++ b/executor/contract/manager/address_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/contract/manager/address_manager_test.cpp b/executor/contract/manager/address_manager_test.cpp index 08287b622..21fd9044c 100644 --- a/executor/contract/manager/address_manager_test.cpp +++ b/executor/contract/manager/address_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/contract/manager/address_manager.h" diff --git a/executor/contract/manager/contract_manager.cpp b/executor/contract/manager/contract_manager.cpp index 3b8ff11c5..426a0b8a3 100644 --- a/executor/contract/manager/contract_manager.cpp +++ b/executor/contract/manager/contract_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/contract/manager/contract_manager.h" diff --git a/executor/contract/manager/contract_manager.h b/executor/contract/manager/contract_manager.h index b645d7286..7e250aa60 100644 --- a/executor/contract/manager/contract_manager.h +++ b/executor/contract/manager/contract_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/contract/manager/contract_manager_test.cpp b/executor/contract/manager/contract_manager_test.cpp index 7b7cc32db..32540bd46 100644 --- a/executor/contract/manager/contract_manager_test.cpp +++ b/executor/contract/manager/contract_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/contract/manager/contract_manager.h" @@ -40,7 +34,7 @@ using ::testing::Test; const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" + std::string(getenv("TEST_WORKSPACE")) + - "/service/contract/executor/manager/"; + "/executor/contract/manager/"; Address get_random_address() { return AddressManager().CreateRandomAddress(); } diff --git a/executor/contract/manager/test_data/BUILD b/executor/contract/manager/test_data/BUILD index 65e3dc3d9..252132954 100644 --- a/executor/contract/manager/test_data/BUILD +++ b/executor/contract/manager/test_data/BUILD @@ -1 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + exports_files(["contract.json"]) diff --git a/executor/contract/manager/utils.h b/executor/contract/manager/utils.h index 2d243d66f..ff9548ca3 100644 --- a/executor/contract/manager/utils.h +++ b/executor/contract/manager/utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/kv/BUILD b/executor/kv/BUILD index 9117dd93b..09f75c240 100644 --- a/executor/kv/BUILD +++ b/executor/kv/BUILD @@ -1,41 +1,31 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") -bool_flag( - name = "enable_leveldb", - build_setting_default = False, - visibility = ["//visibility:public"], -) - -bool_flag( - name = "enable_rocksdb", - build_setting_default = False, - visibility = ["//visibility:public"], -) - -config_setting( - name = "enable_leveldb_setting", - values = { - "define": "enable_leveldb=True", - }, - visibility = ["//visibility:public"], -) - -config_setting( - name = "enable_rocksdb_setting", - values = { - "define": "enable_rocksdb=True", - }, - visibility = ["//visibility:public"], -) - cc_library( name = "kv_executor", srcs = ["kv_executor.cpp"], hdrs = ["kv_executor.h"], deps = [ - "//chain/state:chain_state", + "//chain/storage", "//common:comm", "//executor/common:transaction_manager", "//platform/config:resdb_config_utils", @@ -48,7 +38,7 @@ cc_test( srcs = ["kv_executor_test.cpp"], deps = [ ":kv_executor", - "//chain/storage:mock_storage", + "//chain/storage:memory_db", "//common/test:test_main", ], ) diff --git a/executor/kv/kv_executor.cpp b/executor/kv/kv_executor.cpp index 8d2ecf557..742253b05 100644 --- a/executor/kv/kv_executor.cpp +++ b/executor/kv/kv_executor.cpp @@ -1,38 +1,30 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/kv/kv_executor.h" #include -#include "proto/kv/kv.pb.h" - namespace resdb { -KVExecutor::KVExecutor(std::unique_ptr state) - : state_(std::move(state)) {} +KVExecutor::KVExecutor(std::unique_ptr storage) + : storage_(std::move(storage)) {} std::unique_ptr KVExecutor::ExecuteData( const std::string& request) { @@ -48,34 +40,108 @@ std::unique_ptr KVExecutor::ExecuteData( Set(kv_request.key(), kv_request.value()); } else if (kv_request.cmd() == KVRequest::GET) { kv_response.set_value(Get(kv_request.key())); - } else if (kv_request.cmd() == KVRequest::GETVALUES) { - kv_response.set_value(GetValues()); + } else if (kv_request.cmd() == KVRequest::GETALLVALUES) { + kv_response.set_value(GetAllValues()); } else if (kv_request.cmd() == KVRequest::GETRANGE) { kv_response.set_value(GetRange(kv_request.key(), kv_request.value())); + } else if (kv_request.cmd() == KVRequest::SET_WITH_VERSION) { + SetWithVersion(kv_request.key(), kv_request.value(), kv_request.version()); + } else if (kv_request.cmd() == KVRequest::GET_WITH_VERSION) { + GetWithVersion(kv_request.key(), kv_request.version(), + kv_response.mutable_value_info()); + } else if (kv_request.cmd() == KVRequest::GET_ALL_ITEMS) { + GetAllItems(kv_response.mutable_items()); + } else if (kv_request.cmd() == KVRequest::GET_KEY_RANGE) { + GetKeyRange(kv_request.min_key(), kv_request.max_key(), + kv_response.mutable_items()); + } else if (kv_request.cmd() == KVRequest::GET_HISTORY) { + GetHistory(kv_request.key(), kv_request.min_version(), + kv_request.max_version(), kv_response.mutable_items()); + } else if (kv_request.cmd() == KVRequest::GET_TOP) { + GetTopHistory(kv_request.key(), kv_request.top_number(), + kv_response.mutable_items()); } std::unique_ptr resp_str = std::make_unique(); if (!kv_response.SerializeToString(resp_str.get())) { return nullptr; } - return resp_str; } void KVExecutor::Set(const std::string& key, const std::string& value) { - state_->SetValue(key, value); + storage_->SetValue(key, value); } std::string KVExecutor::Get(const std::string& key) { - return state_->GetValue(key); + return storage_->GetValue(key); } -std::string KVExecutor::GetValues() { return state_->GetAllValues(); } +std::string KVExecutor::GetAllValues() { return storage_->GetAllValues(); } // Get values on a range of keys std::string KVExecutor::GetRange(const std::string& min_key, const std::string& max_key) { - return state_->GetRange(min_key, max_key); + return storage_->GetRange(min_key, max_key); +} + +void KVExecutor::SetWithVersion(const std::string& key, + const std::string& value, int version) { + storage_->SetValueWithVersion(key, value, version); +} + +void KVExecutor::GetWithVersion(const std::string& key, int version, + ValueInfo* info) { + std::pair ret = storage_->GetValueWithVersion(key, version); + info->set_value(ret.first); + info->set_version(ret.second); +} + +void KVExecutor::GetAllItems(Items* items) { + const std::map>& ret = + storage_->GetAllItems(); + for (auto it : ret) { + Item* item = items->add_item(); + item->set_key(it.first); + item->mutable_value_info()->set_value(it.second.first); + item->mutable_value_info()->set_version(it.second.second); + } +} + +void KVExecutor::GetKeyRange(const std::string& min_key, + const std::string& max_key, Items* items) { + const std::map>& ret = + storage_->GetKeyRange(min_key, max_key); + for (auto it : ret) { + Item* item = items->add_item(); + item->set_key(it.first); + item->mutable_value_info()->set_value(it.second.first); + item->mutable_value_info()->set_version(it.second.second); + } +} + +void KVExecutor::GetHistory(const std::string& key, int min_version, + int max_version, Items* items) { + const std::vector>& ret = + storage_->GetHistory(key, min_version, max_version); + for (auto it : ret) { + Item* item = items->add_item(); + item->set_key(key); + item->mutable_value_info()->set_value(it.first); + item->mutable_value_info()->set_version(it.second); + } +} + +void KVExecutor::GetTopHistory(const std::string& key, int top_number, + Items* items) { + const std::vector>& ret = + storage_->GetTopHistory(key, top_number); + for (auto it : ret) { + Item* item = items->add_item(); + item->set_key(key); + item->mutable_value_info()->set_value(it.first); + item->mutable_value_info()->set_version(it.second); + } } } // namespace resdb diff --git a/executor/kv/kv_executor.h b/executor/kv/kv_executor.h index 58392f03f..0fda88ae0 100644 --- a/executor/kv/kv_executor.h +++ b/executor/kv/kv_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once @@ -29,15 +23,15 @@ #include #include -#include "chain/state/chain_state.h" +#include "chain/storage/storage.h" #include "executor/common/transaction_manager.h" -#include "platform/config/resdb_config_utils.h" +#include "proto/kv/kv.pb.h" namespace resdb { class KVExecutor : public TransactionManager { public: - KVExecutor(std::unique_ptr state); + KVExecutor(std::unique_ptr storage); virtual ~KVExecutor() = default; std::unique_ptr ExecuteData(const std::string& request) override; @@ -45,11 +39,21 @@ class KVExecutor : public TransactionManager { protected: virtual void Set(const std::string& key, const std::string& value); std::string Get(const std::string& key); - std::string GetValues(); + std::string GetAllValues(); std::string GetRange(const std::string& min_key, const std::string& max_key); + void SetWithVersion(const std::string& key, const std::string& value, + int version); + void GetWithVersion(const std::string& key, int version, ValueInfo* info); + void GetAllItems(Items* items); + void GetKeyRange(const std::string& min_key, const std::string& max_key, + Items* items); + void GetHistory(const std::string& key, int min_key, int max_key, + Items* items); + void GetTopHistory(const std::string& key, int top_number, Items* items); + private: - std::unique_ptr state_; + std::unique_ptr storage_; }; } // namespace resdb diff --git a/executor/kv/kv_executor_test.cpp b/executor/kv/kv_executor_test.cpp index 17b32a46b..9bf78dc4c 100644 --- a/executor/kv/kv_executor_test.cpp +++ b/executor/kv/kv_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/kv/kv_executor.h" @@ -28,13 +22,17 @@ #include #include -#include "chain/storage/mock_storage.h" +#include "chain/storage/memory_db.h" +#include "chain/storage/storage.h" +#include "common/test/test_macros.h" #include "platform/config/resdb_config_utils.h" #include "proto/kv/kv.pb.h" namespace resdb { namespace { +using ::resdb::testing::EqualsProto; +using storage::MemoryDB; using ::testing::Invoke; using ::testing::Return; using ::testing::Test; @@ -42,10 +40,9 @@ using ::testing::Test; class KVExecutorTest : public Test { public: KVExecutorTest() { - auto mock_storage = std::make_unique(); - mock_storage_ptr_ = mock_storage.get(); - impl_ = std::make_unique( - std::make_unique(std::move(mock_storage))); + auto storage = std::make_unique(); + storage_ptr_ = storage.get(); + impl_ = std::make_unique(std::move(storage)); } int Set(const std::string& key, const std::string& value) { @@ -83,9 +80,9 @@ class KVExecutorTest : public Test { return kv_response.value(); } - std::string GetValues() { + std::string GetAllValues() { KVRequest request; - request.set_cmd(KVRequest::GETVALUES); + request.set_cmd(KVRequest::GETALLVALUES); std::string str; if (!request.SerializeToString(&str)) { @@ -123,8 +120,115 @@ class KVExecutorTest : public Test { return kv_response.value(); } + int Set(const std::string& key, const std::string& value, int version) { + KVRequest request; + request.set_cmd(KVRequest::SET_WITH_VERSION); + request.set_key(key); + request.set_value(value); + request.set_version(version); + + std::string str; + if (!request.SerializeToString(&str)) { + return -1; + } + + impl_->ExecuteData(str); + return 0; + } + + ValueInfo Get(const std::string& key, int version) { + KVRequest request; + request.set_cmd(KVRequest::GET_WITH_VERSION); + request.set_key(key); + request.set_version(version); + + std::string str; + if (!request.SerializeToString(&str)) { + return ValueInfo(); + } + + auto resp = impl_->ExecuteData(str); + if (resp == nullptr) { + return ValueInfo(); + } + KVResponse kv_response; + if (!kv_response.ParseFromString(*resp)) { + return ValueInfo(); + } + + return kv_response.value_info(); + } + + Items GetAllItems() { + KVRequest request; + request.set_cmd(KVRequest::GET_ALL_ITEMS); + + std::string str; + if (!request.SerializeToString(&str)) { + return Items(); + } + + auto resp = impl_->ExecuteData(str); + if (resp == nullptr) { + return Items(); + } + KVResponse kv_response; + if (!kv_response.ParseFromString(*resp)) { + return Items(); + } + + return kv_response.items(); + } + + Items GetKeyRange(const std::string& min_key, const std::string& max_key) { + KVRequest request; + request.set_cmd(KVRequest::GET_KEY_RANGE); + request.set_min_key(min_key); + request.set_max_key(max_key); + + std::string str; + if (!request.SerializeToString(&str)) { + return Items(); + } + + auto resp = impl_->ExecuteData(str); + if (resp == nullptr) { + return Items(); + } + KVResponse kv_response; + if (!kv_response.ParseFromString(*resp)) { + return Items(); + } + + return kv_response.items(); + } + + Items GetHistory(const std::string& key, int min_version, int max_version) { + KVRequest request; + request.set_cmd(KVRequest::GET_HISTORY); + request.set_key(key); + request.set_min_version(min_version); + request.set_max_version(max_version); + + std::string str; + if (!request.SerializeToString(&str)) { + return Items(); + } + + auto resp = impl_->ExecuteData(str); + if (resp == nullptr) { + return Items(); + } + KVResponse kv_response; + if (!kv_response.ParseFromString(*resp)) { + return Items(); + } + + return kv_response.items(); + } + protected: - MockStorage* mock_storage_ptr_; + Storage* storage_ptr_; private: std::unique_ptr impl_; @@ -133,33 +237,105 @@ class KVExecutorTest : public Test { TEST_F(KVExecutorTest, SetValue) { std::map data; - EXPECT_CALL(*mock_storage_ptr_, SetValue("test_key", "test_value")) - .WillOnce(Invoke([&](const std::string& key, const std::string& value) { - data[key] = value; - return 0; - })); + EXPECT_EQ(GetAllValues(), "[]"); + EXPECT_EQ(Set("test_key", "test_value"), 0); + EXPECT_EQ(Get("test_key"), "test_value"); - EXPECT_CALL(*mock_storage_ptr_, GetValue("test_key")) - .WillOnce(Invoke([&](const std::string& key) { - std::string ret = data[key]; - return ret; - })); + // GetAllValues and GetRange may be out of order for in-memory, so we test up + // to 1 key-value pair + EXPECT_EQ(GetAllValues(), "[test_value]"); + EXPECT_EQ(GetRange("a", "z"), "[test_value]"); +} - EXPECT_CALL(*mock_storage_ptr_, GetAllValues()) - .WillOnce(Return("[]")) - .WillOnce(Return("[test_value]")); +TEST_F(KVExecutorTest, SetValueWithVersion) { + std::map data; - EXPECT_CALL(*mock_storage_ptr_, GetRange("a", "z")) - .WillOnce(Return("[test_value]")); + { + EXPECT_EQ(Set("test_key", "test_value", 0), 0); + ValueInfo expected_info; + expected_info.set_value("test_value"); + expected_info.set_version(1); + EXPECT_THAT(Get("test_key", 1), EqualsProto(expected_info)); + } - EXPECT_EQ(GetValues(), "[]"); - EXPECT_EQ(Set("test_key", "test_value"), 0); - EXPECT_EQ(Get("test_key"), "test_value"); + { + EXPECT_EQ(Set("test_key", "test_value1", 1), 0); + ValueInfo expected_info; + expected_info.set_value("test_value1"); + expected_info.set_version(2); + EXPECT_THAT(Get("test_key", 2), EqualsProto(expected_info)); + } + { + EXPECT_EQ(Set("test_key", "test_value1", 1), 0); + ValueInfo expected_info; + expected_info.set_value("test_value"); + expected_info.set_version(1); + EXPECT_THAT(Get("test_key", 1), EqualsProto(expected_info)); + } - // GetValues and GetRange may be out of order for in-memory, so we test up to - // 1 key-value pair - EXPECT_EQ(GetValues(), "[test_value]"); - EXPECT_EQ(GetRange("a", "z"), "[test_value]"); + { + EXPECT_EQ(Set("test_key1", "test_key1", 0), 0); + ValueInfo expected_info; + expected_info.set_value("test_key1"); + expected_info.set_version(1); + EXPECT_THAT(Get("test_key1", 1), EqualsProto(expected_info)); + + ValueInfo expected_info2; + expected_info2.set_value("test_value"); + expected_info2.set_version(1); + EXPECT_THAT(Get("test_key", 1), EqualsProto(expected_info2)); + + ValueInfo expected_info3; + expected_info3.set_value("test_value1"); + expected_info3.set_version(2); + EXPECT_THAT(Get("test_key", 0), EqualsProto(expected_info3)); + } + + { + Items items; + { + Item* item = items.add_item(); + item->set_key("test_key"); + item->mutable_value_info()->set_value("test_value1"); + item->mutable_value_info()->set_version(2); + } + { + Item* item = items.add_item(); + item->set_key("test_key1"); + item->mutable_value_info()->set_value("test_key1"); + item->mutable_value_info()->set_version(1); + } + + EXPECT_THAT(GetAllItems(), EqualsProto(items)); + } + + { + Items items; + { + Item* item = items.add_item(); + item->set_key("test_key"); + item->mutable_value_info()->set_value("test_value1"); + item->mutable_value_info()->set_version(2); + } + EXPECT_THAT(GetKeyRange("test_key", "test_key"), EqualsProto(items)); + } + + { + Items items; + { + Item* item = items.add_item(); + item->set_key("test_key"); + item->mutable_value_info()->set_value("test_value1"); + item->mutable_value_info()->set_version(2); + } + { + Item* item = items.add_item(); + item->set_key("test_key"); + item->mutable_value_info()->set_value("test_value"); + item->mutable_value_info()->set_version(1); + } + EXPECT_THAT(GetHistory("test_key", 0, 2), EqualsProto(items)); + } } } // namespace diff --git a/executor/utxo/executor/BUILD b/executor/utxo/executor/BUILD index 013e4ad61..2a4fb9389 100644 --- a/executor/utxo/executor/BUILD +++ b/executor/utxo/executor/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/executor/utxo/executor/utxo_executor.cpp b/executor/utxo/executor/utxo_executor.cpp index ff84f7ddc..a60e535a1 100644 --- a/executor/utxo/executor/utxo_executor.cpp +++ b/executor/utxo/executor/utxo_executor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/utxo/executor/utxo_executor.h" diff --git a/executor/utxo/executor/utxo_executor.h b/executor/utxo/executor/utxo_executor.h index a0b625424..2e9acf8bc 100644 --- a/executor/utxo/executor/utxo_executor.h +++ b/executor/utxo/executor/utxo_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/utxo/executor/utxo_executor_test.cpp b/executor/utxo/executor/utxo_executor_test.cpp index cda4a8396..0de5d69d0 100644 --- a/executor/utxo/executor/utxo_executor_test.cpp +++ b/executor/utxo/executor/utxo_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/utxo/executor/utxo_executor.h" diff --git a/executor/utxo/manager/BUILD b/executor/utxo/manager/BUILD index 13958c409..77f125f4f 100644 --- a/executor/utxo/manager/BUILD +++ b/executor/utxo/manager/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//executor/utxo:__subpackages__"]) cc_library( diff --git a/executor/utxo/manager/transaction.cpp b/executor/utxo/manager/transaction.cpp index b2c750677..787e20118 100644 --- a/executor/utxo/manager/transaction.cpp +++ b/executor/utxo/manager/transaction.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/utxo/manager/transaction.h" diff --git a/executor/utxo/manager/transaction.h b/executor/utxo/manager/transaction.h index 238101af3..556d75b08 100644 --- a/executor/utxo/manager/transaction.h +++ b/executor/utxo/manager/transaction.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/utxo/manager/transaction_test.cpp b/executor/utxo/manager/transaction_test.cpp index 0fe154d78..50e239f0a 100644 --- a/executor/utxo/manager/transaction_test.cpp +++ b/executor/utxo/manager/transaction_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/utxo/manager/transaction.h" diff --git a/executor/utxo/manager/tx_mempool.cpp b/executor/utxo/manager/tx_mempool.cpp index 889b1fea6..ef832bc63 100644 --- a/executor/utxo/manager/tx_mempool.cpp +++ b/executor/utxo/manager/tx_mempool.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/utxo/manager/tx_mempool.h" diff --git a/executor/utxo/manager/tx_mempool.h b/executor/utxo/manager/tx_mempool.h index 13af92bd5..808361b40 100644 --- a/executor/utxo/manager/tx_mempool.h +++ b/executor/utxo/manager/tx_mempool.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/utxo/manager/tx_mempool_test.cpp b/executor/utxo/manager/tx_mempool_test.cpp index 205ad66c9..a9af05176 100644 --- a/executor/utxo/manager/tx_mempool_test.cpp +++ b/executor/utxo/manager/tx_mempool_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/utxo/manager/tx_mempool.h" diff --git a/executor/utxo/manager/wallet.cpp b/executor/utxo/manager/wallet.cpp index b69e7568c..644b35d90 100644 --- a/executor/utxo/manager/wallet.cpp +++ b/executor/utxo/manager/wallet.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/utxo/manager/wallet.h" diff --git a/executor/utxo/manager/wallet.h b/executor/utxo/manager/wallet.h index 5ed03c1ac..b9755515f 100644 --- a/executor/utxo/manager/wallet.h +++ b/executor/utxo/manager/wallet.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/executor/utxo/manager/wallet_test.cpp b/executor/utxo/manager/wallet_test.cpp index ebf6e2b35..6e606e207 100644 --- a/executor/utxo/manager/wallet_test.cpp +++ b/executor/utxo/manager/wallet_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "executor/utxo/manager/wallet.h" diff --git a/img/apache-incubator.png b/img/apache-incubator.png new file mode 100644 index 0000000000000000000000000000000000000000..338169e4d0698881d3494d80b16232bb5d77c122 GIT binary patch literal 30207 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 QanC}Mmj;7MKbZvnAJyS{jQ{`u literal 0 HcmV?d00001 diff --git a/img/apache-resdb.png b/img/apache-resdb.png new file mode 100644 index 0000000000000000000000000000000000000000..1e2d0a0a9fc5375e7834a5490d85095a873fe80b GIT binary patch literal 98785 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
oVlDywcVB3dd0)hwG@iM7I#0I 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 TKf#K(5YwY4juaj~|L6Y!D_ZJ; literal 0 HcmV?d00001 diff --git a/img/resdb.png b/img/resdb.png new file mode 100644 index 0000000000000000000000000000000000000000..bce6eb40c221f60df2c4f9b97d7935a9b4de2437 GIT binary patch literal 36015 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 literal 0 HcmV?d00001 diff --git a/interface/common/BUILD b/interface/common/BUILD index e5765e1e8..63f5bdeea 100644 --- a/interface/common/BUILD +++ b/interface/common/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/interface/common/mock_resdb_txn_accessor.h b/interface/common/mock_resdb_txn_accessor.h index c900dba47..3962ba275 100644 --- a/interface/common/mock_resdb_txn_accessor.h +++ b/interface/common/mock_resdb_txn_accessor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/interface/common/resdb_state_accessor.cpp b/interface/common/resdb_state_accessor.cpp index 9dbc847c7..ec7033ea6 100644 --- a/interface/common/resdb_state_accessor.cpp +++ b/interface/common/resdb_state_accessor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/common/resdb_state_accessor.h" @@ -41,8 +35,7 @@ std::unique_ptr ResDBStateAccessor::GetNetChannel( } // Obtain ReplicaState of each replica. -absl::StatusOr> -ResDBStateAccessor::GetReplicaStates() { +absl::StatusOr ResDBStateAccessor::GetReplicaState() { const auto& client_info = config_.GetReplicaInfos()[0]; Request request; @@ -55,24 +48,12 @@ ResDBStateAccessor::GetReplicaStates() { return absl::InternalError("send data fail."); } - std::unique_ptr state = std::make_unique(); - ret = client->RecvRawMessage(state.get()); + ReplicaState state; + ret = client->RecvRawMessage(&state); if (ret < 0) { return absl::InternalError("recv data fail."); } - if (state == nullptr) { - return absl::InternalError("recv data fail."); - } - - std::vector resp; - for (const auto& region : state->replica_config().region()) { - for (const auto& info : region.replica_info()) { - ReplicaState new_state; - *new_state.mutable_replica_info() = info; - resp.push_back(new_state); - } - } - return resp; + return state; } } // namespace resdb diff --git a/interface/common/resdb_state_accessor.h b/interface/common/resdb_state_accessor.h index 8ce5dbede..8410547bf 100644 --- a/interface/common/resdb_state_accessor.h +++ b/interface/common/resdb_state_accessor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once @@ -40,7 +34,7 @@ class ResDBStateAccessor { virtual ~ResDBStateAccessor() = default; // Obtain ReplicaState of each replica. - absl::StatusOr> GetReplicaStates(); + absl::StatusOr GetReplicaState(); protected: virtual std::unique_ptr GetNetChannel(const std::string& ip, diff --git a/interface/common/resdb_state_accessor_test.cpp b/interface/common/resdb_state_accessor_test.cpp index 77e0954f0..ad27ca5f8 100644 --- a/interface/common/resdb_state_accessor_test.cpp +++ b/interface/common/resdb_state_accessor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/common/resdb_state_accessor.h" @@ -35,6 +29,7 @@ namespace resdb { namespace { using ::google::protobuf::util::MessageDifferencer; +using ::resdb::testing::EqualsProto; using ::testing::ElementsAre; using ::testing::Invoke; using ::testing::Test; @@ -101,18 +96,9 @@ TEST_F(StateClientTest, GetAllReplicaState) { })); return client; })); - auto ret = client.GetReplicaStates(); + auto ret = client.GetReplicaState(); EXPECT_TRUE(ret.ok()); - std::set results; - for (auto& state : *ret) { - auto it = std::find_if( - replicas_.begin(), replicas_.end(), [&](const ReplicaInfo& info) { - return MessageDifferencer::Equals(info, state.replica_info()); - }); - EXPECT_TRUE(it != replicas_.end()); - results.insert(it - replicas_.begin()); - } - EXPECT_EQ(results.size(), 4); + EXPECT_THAT(state, EqualsProto(*ret)); } } // namespace diff --git a/interface/common/resdb_txn_accessor.cpp b/interface/common/resdb_txn_accessor.cpp index b6e4fb137..3b7751916 100644 --- a/interface/common/resdb_txn_accessor.cpp +++ b/interface/common/resdb_txn_accessor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/common/resdb_txn_accessor.h" @@ -153,4 +147,45 @@ absl::StatusOr> ResDBTxnAccessor::GetRequestFromReplica( return txn_resp; } +absl::StatusOr ResDBTxnAccessor::GetBlockNumbers() { + QueryRequest request; + request.set_min_seq(0); + request.set_max_seq(0); + + std::vector> clients; + std::vector ths; + std::string final_str; + std::mutex mtx; + std::condition_variable resp_cv; + bool success = false; + + std::unique_ptr client = + GetNetChannel(replicas_[0].ip(), replicas_[0].port()); + + LOG(INFO) << "ip:" << replicas_[0].ip() << " port:" << replicas_[0].port(); + + std::string response_str; + int ret = 0; + for (int i = 0; i < 5; ++i) { + ret = client->SendRequest(request, Request::TYPE_QUERY); + if (ret) { + continue; + } + client->SetRecvTimeout(100000); + ret = client->RecvRawMessageStr(&response_str); + LOG(INFO) << "receive str:" << ret << " len:" << response_str.size(); + if (ret != 0) { + continue; + } + break; + } + + QueryResponse resp; + if (response_str.empty() || !resp.ParseFromString(response_str)) { + LOG(ERROR) << "parse fail len:" << final_str.size(); + return absl::InternalError("recv data fail."); + } + return resp.max_seq(); +} + } // namespace resdb diff --git a/interface/common/resdb_txn_accessor.h b/interface/common/resdb_txn_accessor.h index 5aa1305b7..6f1e1fd99 100644 --- a/interface/common/resdb_txn_accessor.h +++ b/interface/common/resdb_txn_accessor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once @@ -45,6 +39,7 @@ class ResDBTxnAccessor { virtual absl::StatusOr> GetRequestFromReplica( uint64_t min_seq, uint64_t max_seq, const ReplicaInfo& replica); + virtual absl::StatusOr GetBlockNumbers(); protected: virtual std::unique_ptr GetNetChannel(const std::string& ip, diff --git a/interface/common/resdb_txn_accessor_test.cpp b/interface/common/resdb_txn_accessor_test.cpp index f7832c2e0..39c407bc2 100644 --- a/interface/common/resdb_txn_accessor_test.cpp +++ b/interface/common/resdb_txn_accessor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/common/resdb_txn_accessor.h" @@ -38,6 +32,7 @@ namespace { using ::resdb::testing::EqualsProto; using ::testing::_; +using ::testing::AtLeast; using ::testing::ElementsAre; using ::testing::Invoke; using ::testing::Pointee; @@ -67,9 +62,11 @@ TEST(ResDBTxnAccessorTest, GetTransactionsFail) { auto client = std::make_unique(ip, port); EXPECT_CALL(*client, SendRequest(EqualsProto(request), Request::TYPE_QUERY, _)) - .WillOnce(Return(0)); + .Times(AtLeast(1)) + .WillRepeatedly(Return(0)); EXPECT_CALL(*client, RecvRawMessageStr) - .WillOnce(Invoke([&](std::string* resp) { return -1; })); + .Times(AtLeast(1)) + .WillRepeatedly(Invoke([&](std::string* resp) { return -1; })); return client; })); absl::StatusOr>> resp = diff --git a/interface/contract/BUILD b/interface/contract/BUILD index f31924fbf..f52239309 100644 --- a/interface/contract/BUILD +++ b/interface/contract/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/interface/contract/contract_client.cpp b/interface/contract/contract_client.cpp index a2d944b9e..2d8b2e98e 100644 --- a/interface/contract/contract_client.cpp +++ b/interface/contract/contract_client.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/contract/contract_client.h" diff --git a/interface/contract/contract_client.h b/interface/contract/contract_client.h index 69e2d4052..7b0c5aed3 100644 --- a/interface/contract/contract_client.h +++ b/interface/contract/contract_client.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/interface/kv/BUILD b/interface/kv/BUILD index 2acf36366..e90fb9ef0 100644 --- a/interface/kv/BUILD +++ b/interface/kv/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/interface/kv/kv_client.cpp b/interface/kv/kv_client.cpp index e3a3e7e48..25526395b 100644 --- a/interface/kv/kv_client.cpp +++ b/interface/kv/kv_client.cpp @@ -1,34 +1,26 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/kv/kv_client.h" #include -#include "proto/kv/kv.pb.h" - namespace resdb { KVClient::KVClient(const ResDBConfig& config) @@ -55,9 +47,9 @@ std::unique_ptr KVClient::Get(const std::string& key) { return std::make_unique(response.value()); } -std::unique_ptr KVClient::GetValues() { +std::unique_ptr KVClient::GetAllValues() { KVRequest request; - request.set_cmd(KVRequest::GETVALUES); + request.set_cmd(KVRequest::GETALLVALUES); KVResponse response; int ret = SendRequest(request, &response); if (ret != 0) { @@ -82,4 +74,75 @@ std::unique_ptr KVClient::GetRange(const std::string& min_key, return std::make_unique(response.value()); } +int KVClient::Set(const std::string& key, const std::string& data, + int version) { + KVRequest request; + request.set_cmd(KVRequest::SET_WITH_VERSION); + request.set_key(key); + request.set_value(data); + request.set_version(version); + return SendRequest(request); +} + +std::unique_ptr KVClient::Get(const std::string& key, int version) { + KVRequest request; + request.set_cmd(KVRequest::GET_WITH_VERSION); + request.set_key(key); + request.set_version(version); + KVResponse response; + int ret = SendRequest(request, &response); + if (ret != 0) { + LOG(ERROR) << "send request fail, ret:" << ret; + return nullptr; + } + return std::make_unique(response.value_info()); +} + +std::unique_ptr KVClient::GetKeyRange(const std::string& min_key, + const std::string& max_key) { + KVRequest request; + request.set_cmd(KVRequest::GET_KEY_RANGE); + request.set_min_key(min_key); + request.set_max_key(max_key); + KVResponse response; + int ret = SendRequest(request, &response); + if (ret != 0) { + LOG(ERROR) << "send request fail, ret:" << ret; + return nullptr; + } + return std::make_unique(response.items()); +} + +std::unique_ptr KVClient::GetKeyHistory(const std::string& key, + int min_version, + int max_version) { + KVRequest request; + request.set_cmd(KVRequest::GET_HISTORY); + request.set_key(key); + request.set_min_version(min_version); + request.set_max_version(max_version); + KVResponse response; + int ret = SendRequest(request, &response); + if (ret != 0) { + LOG(ERROR) << "send request fail, ret:" << ret; + return nullptr; + } + return std::make_unique(response.items()); +} + +std::unique_ptr KVClient::GetKeyTopHistory(const std::string& key, + int top_number) { + KVRequest request; + request.set_cmd(KVRequest::GET_TOP); + request.set_key(key); + request.set_top_number(top_number); + KVResponse response; + int ret = SendRequest(request, &response); + if (ret != 0) { + LOG(ERROR) << "send request fail, ret:" << ret; + return nullptr; + } + return std::make_unique(response.items()); +} + } // namespace resdb diff --git a/interface/kv/kv_client.h b/interface/kv/kv_client.h index 03724d380..52cbcab19 100644 --- a/interface/kv/kv_client.h +++ b/interface/kv/kv_client.h @@ -1,31 +1,26 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once #include "interface/rdbc/transaction_constructor.h" +#include "proto/kv/kv.pb.h" namespace resdb { @@ -34,9 +29,36 @@ class KVClient : public TransactionConstructor { public: KVClient(const ResDBConfig& config); + // Version-based interfaces. + // Obtain the current version before setting a new data + int Set(const std::string& key, const std::string& data, int version); + + // Obtain the value with a specific version. + // If the version parameter is zero, it will return the data with the current + // version in the database. ValueInfo contains the version and its version. + // Return nullptr if there is an error. + std::unique_ptr Get(const std::string& key, int version); + + // Obtain the latest values of the keys within [min_key, max_key]. + // Keys should be comparable. + std::unique_ptr GetKeyRange(const std::string& min_key, + const std::string& max_key); + + // Obtain the histories of `key` with the versions in [min_version, + // max_version] + std::unique_ptr GetKeyHistory(const std::string& key, int min_version, + int max_version); + + // Obtain the top `top_number` histories of the `key`. + std::unique_ptr GetKeyTopHistory(const std::string& key, + int top_number); + + // Non-version-based Interfaces. + // These interfaces are not compatible with the version-based interfaces + // above. int Set(const std::string& key, const std::string& data); std::unique_ptr Get(const std::string& key); - std::unique_ptr GetValues(); + std::unique_ptr GetAllValues(); std::unique_ptr GetRange(const std::string& min_key, const std::string& max_key); }; diff --git a/interface/rdbc/BUILD b/interface/rdbc/BUILD index b1137dbfb..e51e677c1 100644 --- a/interface/rdbc/BUILD +++ b/interface/rdbc/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/interface/rdbc/mock_net_channel.h b/interface/rdbc/mock_net_channel.h index 39874da1f..73785c226 100644 --- a/interface/rdbc/mock_net_channel.h +++ b/interface/rdbc/mock_net_channel.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/interface/rdbc/mock_resdb_txn_accessor.h b/interface/rdbc/mock_resdb_txn_accessor.h index 281c05103..f70fa9a31 100644 --- a/interface/rdbc/mock_resdb_txn_accessor.h +++ b/interface/rdbc/mock_resdb_txn_accessor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/interface/rdbc/net_channel.cpp b/interface/rdbc/net_channel.cpp index c4999c4bc..981b0af29 100644 --- a/interface/rdbc/net_channel.cpp +++ b/interface/rdbc/net_channel.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/rdbc/net_channel.h" diff --git a/interface/rdbc/net_channel.h b/interface/rdbc/net_channel.h index 53b1578e2..d1baa692e 100644 --- a/interface/rdbc/net_channel.h +++ b/interface/rdbc/net_channel.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/interface/rdbc/net_channel_test.cpp b/interface/rdbc/net_channel_test.cpp index 1ac81a024..a0da76755 100644 --- a/interface/rdbc/net_channel_test.cpp +++ b/interface/rdbc/net_channel_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/rdbc/net_channel.h" diff --git a/interface/rdbc/transaction_constructor.cpp b/interface/rdbc/transaction_constructor.cpp index f71433484..be42224aa 100644 --- a/interface/rdbc/transaction_constructor.cpp +++ b/interface/rdbc/transaction_constructor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/rdbc/transaction_constructor.h" diff --git a/interface/rdbc/transaction_constructor.h b/interface/rdbc/transaction_constructor.h index c305badf3..39754a846 100644 --- a/interface/rdbc/transaction_constructor.h +++ b/interface/rdbc/transaction_constructor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/interface/rdbc/transaction_constructor_test.cpp b/interface/rdbc/transaction_constructor_test.cpp index 1dda2a895..cd00646d1 100644 --- a/interface/rdbc/transaction_constructor_test.cpp +++ b/interface/rdbc/transaction_constructor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/rdbc/transaction_constructor.h" diff --git a/interface/utxo/BUILD b/interface/utxo/BUILD index 7079e644b..b47bb9975 100644 --- a/interface/utxo/BUILD +++ b/interface/utxo/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/interface/utxo/utxo_client.cpp b/interface/utxo/utxo_client.cpp index fa68656a3..8ed006f1a 100644 --- a/interface/utxo/utxo_client.cpp +++ b/interface/utxo/utxo_client.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "interface/utxo/utxo_client.h" diff --git a/interface/utxo/utxo_client.h b/interface/utxo/utxo_client.h index b42175452..9cf0d8fce 100644 --- a/interface/utxo/utxo_client.h +++ b/interface/utxo/utxo_client.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/monitoring/README.md b/monitoring/README.md index 2e8c4cc9f..ddd425729 100644 --- a/monitoring/README.md +++ b/monitoring/README.md @@ -1,3 +1,22 @@ + + # Download Prometheus wget https://github.com/prometheus/prometheus/releases/download/v2.47.0/prometheus-2.47.0.linux-amd64.tar.gz tar xvf prometheus-2.47.0.linux-amd64.tar.gz diff --git a/monitoring/prometheus/prometheus.yml b/monitoring/prometheus/prometheus.yml index c0046d381..39c18fcfa 100644 --- a/monitoring/prometheus/prometheus.yml +++ b/monitoring/prometheus/prometheus.yml @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + # my global config global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. @@ -25,19 +44,19 @@ scrape_configs: - targets: ["localhost:9090"] - job_name: "node_exporter1" static_configs: - - targets: ["172.31.52.247:9100"] + - targets: ["localhost:9100"] - job_name: "node_exporter2" static_configs: - - targets: ["172.31.54.193:9100"] + - targets: ["localhost:9100"] - job_name: "node_exporter3" static_configs: - - targets: ["172.31.55.48:9100"] + - targets: ["localhost:9100"] - job_name: "node_exporter4" static_configs: - - targets: ["172.31.53.140:9100"] + - targets: ["localhost:9100"] - job_name: "node_exporter5" static_configs: - - targets: ["172.31.57.186:9100"] + - targets: ["localhost:9100"] - job_name: "cpp_client1" static_configs: - targets: ["172.31.52.247:8090"] diff --git a/node_modules/@actions/core/README.md b/node_modules/@actions/core/README.md deleted file mode 100644 index 5ad27eede..000000000 --- a/node_modules/@actions/core/README.md +++ /dev/null @@ -1,146 +0,0 @@ -# `@actions/core` - -> Core functions for setting results, logging, registering secrets and exporting variables across actions - -## Usage - -### Import the package - -```js -// javascript -const core = require('@actions/core'); - -// typescript -import * as core from '@actions/core'; -``` - -#### Inputs/Outputs - -Action inputs can be read with `getInput`. Outputs can be set with `setOutput` which makes them available to be mapped into inputs of other actions to ensure they are decoupled. - -```js -const myInput = core.getInput('inputName', { required: true }); - -core.setOutput('outputKey', 'outputVal'); -``` - -#### Exporting variables - -Since each step runs in a separate process, you can use `exportVariable` to add it to this step and future steps environment blocks. - -```js -core.exportVariable('envVar', 'Val'); -``` - -#### Setting a secret - -Setting a secret registers the secret with the runner to ensure it is masked in logs. - -```js -core.setSecret('myPassword'); -``` - -#### PATH Manipulation - -To make a tool's path available in the path for the remainder of the job (without altering the machine or containers state), use `addPath`. The runner will prepend the path given to the jobs PATH. - -```js -core.addPath('/path/to/mytool'); -``` - -#### Exit codes - -You should use this library to set the failing exit code for your action. If status is not set and the script runs to completion, that will lead to a success. - -```js -const core = require('@actions/core'); - -try { - // Do stuff -} -catch (err) { - // setFailed logs the message and sets a failing exit code - core.setFailed(`Action failed with error ${err}`); -} - -Note that `setNeutral` is not yet implemented in actions V2 but equivalent functionality is being planned. - -``` - -#### Logging - -Finally, this library provides some utilities for logging. Note that debug logging is hidden from the logs by default. This behavior can be toggled by enabling the [Step Debug Logs](../../docs/action-debugging.md#step-debug-logs). - -```js -const core = require('@actions/core'); - -const myInput = core.getInput('input'); -try { - core.debug('Inside try block'); - - if (!myInput) { - core.warning('myInput was not set'); - } - - if (core.isDebug()) { - // curl -v https://github.com - } else { - // curl https://github.com - } - - // Do stuff -} -catch (err) { - core.error(`Error ${err}, action may still succeed though`); -} -``` - -This library can also wrap chunks of output in foldable groups. - -```js -const core = require('@actions/core') - -// Manually wrap output -core.startGroup('Do some function') -doSomeFunction() -core.endGroup() - -// Wrap an asynchronous function call -const result = await core.group('Do something async', async () => { - const response = await doSomeHTTPRequest() - return response -}) -``` - -#### Action state - -You can use this library to save state and get state for sharing information between a given wrapper action: - -**action.yml** -```yaml -name: 'Wrapper action sample' -inputs: - name: - default: 'GitHub' -runs: - using: 'node12' - main: 'main.js' - post: 'cleanup.js' -``` - -In action's `main.js`: - -```js -const core = require('@actions/core'); - -core.saveState("pidToKill", 12345); -``` - -In action's `cleanup.js`: -```js -const core = require('@actions/core'); - -var pid = core.getState("pidToKill"); - -process.kill(pid); -``` \ No newline at end of file diff --git a/node_modules/@actions/core/lib/command.d.ts b/node_modules/@actions/core/lib/command.d.ts deleted file mode 100644 index 51b8f116d..000000000 --- a/node_modules/@actions/core/lib/command.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -interface CommandProperties { - [key: string]: string; -} -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -export declare function issueCommand(command: string, properties: CommandProperties, message: string): void; -export declare function issue(name: string, message?: string): void; -export {}; diff --git a/node_modules/@actions/core/lib/command.js b/node_modules/@actions/core/lib/command.js deleted file mode 100644 index eeef233ee..000000000 --- a/node_modules/@actions/core/lib/command.js +++ /dev/null @@ -1,78 +0,0 @@ -"use strict"; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const os = __importStar(require("os")); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } -} -function escapeData(s) { - return (s || '') - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return (s || '') - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map \ No newline at end of file diff --git a/node_modules/@actions/core/lib/command.js.map b/node_modules/@actions/core/lib/command.js.map deleted file mode 100644 index 00a9861e6..000000000 --- a/node_modules/@actions/core/lib/command.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAwB;AAQxB;;;;;;;;;GASG;AACH,SAAgB,YAAY,CAC1B,OAAe,EACf,UAA6B,EAC7B,OAAe;IAEf,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AAC/C,CAAC;AAPD,oCAOC;AAED,SAAgB,KAAK,CAAC,IAAY,EAAE,UAAkB,EAAE;IACtD,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACjC,CAAC;AAFD,sBAEC;AAED,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,OAAO;IAKX,YAAY,OAAe,EAAE,UAA6B,EAAE,OAAe;QACzE,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,GAAG,iBAAiB,CAAA;SAC5B;QAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,QAAQ;QACN,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,OAAO,CAAA;QAEtC,IAAI,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAC9D,MAAM,IAAI,GAAG,CAAA;YACb,IAAI,KAAK,GAAG,IAAI,CAAA;YAChB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE;gBACjC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;oBACvC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;oBAChC,IAAI,GAAG,EAAE;wBACP,IAAI,KAAK,EAAE;4BACT,KAAK,GAAG,KAAK,CAAA;yBACd;6BAAM;4BACL,MAAM,IAAI,GAAG,CAAA;yBACd;wBAED,MAAM,IAAI,GAAG,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAA;qBAC1C;iBACF;aACF;SACF;QAED,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;QACpD,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;SACb,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,CAAS;IAC/B,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;SACb,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACzB,CAAC"} \ No newline at end of file diff --git a/node_modules/@actions/core/lib/core.d.ts b/node_modules/@actions/core/lib/core.d.ts deleted file mode 100644 index 8fcc31bae..000000000 --- a/node_modules/@actions/core/lib/core.d.ts +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Interface for getInput options - */ -export interface InputOptions { - /** Optional. Whether the input is required. If required and not present, will throw. Defaults to false */ - required?: boolean; -} -/** - * The code to exit an action - */ -export declare enum ExitCode { - /** - * A code indicating that the action was successful - */ - Success = 0, - /** - * A code indicating that the action was a failure - */ - Failure = 1 -} -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable - */ -export declare function exportVariable(name: string, val: string): void; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -export declare function setSecret(secret: string): void; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -export declare function addPath(inputPath: string): void; -/** - * Gets the value of an input. The value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -export declare function getInput(name: string, options?: InputOptions): string; -/** - * Sets the value of an output. - * - * @param name name of the output to set - * @param value value to store - */ -export declare function setOutput(name: string, value: string): void; -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -export declare function setFailed(message: string): void; -/** - * Gets whether Actions Step Debug is on or not - */ -export declare function isDebug(): boolean; -/** - * Writes debug message to user log - * @param message debug message - */ -export declare function debug(message: string): void; -/** - * Adds an error issue - * @param message error issue message - */ -export declare function error(message: string): void; -/** - * Adds an warning issue - * @param message warning issue message - */ -export declare function warning(message: string): void; -/** - * Writes info to log with console.log. - * @param message info message - */ -export declare function info(message: string): void; -/** - * Begin an output group. - * - * Output until the next `groupEnd` will be foldable in this group - * - * @param name The name of the output group - */ -export declare function startGroup(name: string): void; -/** - * End an output group. - */ -export declare function endGroup(): void; -/** - * Wrap an asynchronous function call in a group. - * - * Returns the same type as the function itself. - * - * @param name The name of the group - * @param fn The function to wrap in the group - */ -export declare function group(name: string, fn: () => Promise): Promise; -/** - * Saves state for current action, the state can only be retrieved by this action's post job execution. - * - * @param name name of the state to store - * @param value value to store - */ -export declare function saveState(name: string, value: string): void; -/** - * Gets the value of an state set by this action's main execution. - * - * @param name name of the state to get - * @returns string - */ -export declare function getState(name: string): string; diff --git a/node_modules/@actions/core/lib/core.js b/node_modules/@actions/core/lib/core.js deleted file mode 100644 index b7ec8ab45..000000000 --- a/node_modules/@actions/core/lib/core.js +++ /dev/null @@ -1,209 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const command_1 = require("./command"); -const os = __importStar(require("os")); -const path = __importStar(require("path")); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable - */ -function exportVariable(name, val) { - process.env[name] = val; - command_1.issueCommand('set-env', { name }, val); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - command_1.issueCommand('add-path', {}, inputPath); - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. The value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Sets the value of an output. - * - * @param name name of the output to set - * @param value value to store - */ -function setOutput(name, value) { - command_1.issueCommand('set-output', { name }, value); -} -exports.setOutput = setOutput; -//----------------------------------------------------------------------- -// Results -//----------------------------------------------------------------------- -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); -} -exports.setFailed = setFailed; -//----------------------------------------------------------------------- -// Logging Commands -//----------------------------------------------------------------------- -/** - * Gets whether Actions Step Debug is on or not - */ -function isDebug() { - return process.env['RUNNER_DEBUG'] === '1'; -} -exports.isDebug = isDebug; -/** - * Writes debug message to user log - * @param message debug message - */ -function debug(message) { - command_1.issueCommand('debug', {}, message); -} -exports.debug = debug; -/** - * Adds an error issue - * @param message error issue message - */ -function error(message) { - command_1.issue('error', message); -} -exports.error = error; -/** - * Adds an warning issue - * @param message warning issue message - */ -function warning(message) { - command_1.issue('warning', message); -} -exports.warning = warning; -/** - * Writes info to log with console.log. - * @param message info message - */ -function info(message) { - process.stdout.write(message + os.EOL); -} -exports.info = info; -/** - * Begin an output group. - * - * Output until the next `groupEnd` will be foldable in this group - * - * @param name The name of the output group - */ -function startGroup(name) { - command_1.issue('group', name); -} -exports.startGroup = startGroup; -/** - * End an output group. - */ -function endGroup() { - command_1.issue('endgroup'); -} -exports.endGroup = endGroup; -/** - * Wrap an asynchronous function call in a group. - * - * Returns the same type as the function itself. - * - * @param name The name of the group - * @param fn The function to wrap in the group - */ -function group(name, fn) { - return __awaiter(this, void 0, void 0, function* () { - startGroup(name); - let result; - try { - result = yield fn(); - } - finally { - endGroup(); - } - return result; - }); -} -exports.group = group; -//----------------------------------------------------------------------- -// Wrapper action state -//----------------------------------------------------------------------- -/** - * Saves state for current action, the state can only be retrieved by this action's post job execution. - * - * @param name name of the state to store - * @param value value to store - */ -function saveState(name, value) { - command_1.issueCommand('save-state', { name }, value); -} -exports.saveState = saveState; -/** - * Gets the value of an state set by this action's main execution. - * - * @param name name of the state to get - * @returns string - */ -function getState(name) { - return process.env[`STATE_${name}`] || ''; -} -exports.getState = getState; -//# sourceMappingURL=core.js.map \ No newline at end of file diff --git a/node_modules/@actions/core/lib/core.js.map b/node_modules/@actions/core/lib/core.js.map deleted file mode 100644 index fb93bd383..000000000 --- a/node_modules/@actions/core/lib/core.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@actions/core/package.json b/node_modules/@actions/core/package.json deleted file mode 100644 index af6022bd9..000000000 --- a/node_modules/@actions/core/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "_from": "@actions/core", - "_id": "@actions/core@1.2.3", - "_inBundle": false, - "_integrity": "sha512-Wp4xnyokakM45Uuj4WLUxdsa8fJjKVl1fDTsPbTEcTcuu0Nb26IPQbOtjmnfaCPGcaoPOOqId8H9NapZ8gii4w==", - "_location": "/@actions/core", - "_phantomChildren": {}, - "_requested": { - "type": "tag", - "registry": true, - "raw": "@actions/core", - "name": "@actions/core", - "escapedName": "@actions%2fcore", - "scope": "@actions", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#USER", - "/" - ], - "_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.3.tgz", - "_shasum": "e844b4fa0820e206075445079130868f95bfca95", - "_spec": "@actions/core", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge", - "bugs": { - "url": "https://github.com/actions/toolkit/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Actions core lib", - "devDependencies": { - "@types/node": "^12.0.2" - }, - "directories": { - "lib": "lib", - "test": "__tests__" - }, - "files": [ - "lib" - ], - "homepage": "https://github.com/actions/toolkit/tree/master/packages/core", - "keywords": [ - "github", - "actions", - "core" - ], - "license": "MIT", - "main": "lib/core.js", - "name": "@actions/core", - "publishConfig": { - "access": "public" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/actions/toolkit.git", - "directory": "packages/core" - }, - "scripts": { - "audit-moderate": "npm install && npm audit --audit-level=moderate", - "test": "echo \"Error: run tests from root\" && exit 1", - "tsc": "tsc" - }, - "types": "lib/core.d.ts", - "version": "1.2.3" -} diff --git a/node_modules/badgen/LICENSE.md b/node_modules/badgen/LICENSE.md deleted file mode 100644 index 13e5e8041..000000000 --- a/node_modules/badgen/LICENSE.md +++ /dev/null @@ -1,5 +0,0 @@ -Copyright 2018 Amio - -Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/badgen/README.md b/node_modules/badgen/README.md deleted file mode 100644 index 852eea304..000000000 --- a/node_modules/badgen/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# badgen - -[![npm version][npm-src]][npm-href] -[![Coverage Status][coveralls-src]][coveralls-href] -[![Bundle size][bundlephobia-src]][bundlephobia-href] -[![License][license-src]][license-href] - -Fast handcraft svg badge generator. Used on [badgen.net](https://badgen.net). - -- 🌀 Zero dependency -- ⚡️ Fast by design (see [benchmarks](#benchmarks)) -- 👯‍ Running in node & browser - -## Usage - -`npm install badgen` - -```javascript -const { badgen } = require('badgen') - -// only `status` is required. -const svgString = badgen({ - label: 'npm', // - labelColor: 'ADF' // or (default: '555') - status: 'v1.2.3', // , required - color: 'blue', // or (default: 'blue') - style: 'flat', // 'flat' or 'classic' (default: 'classic') - icon: 'data:image/svg+xml;base64,...', // Use icon (default: undefined) - iconWidth: 13, // Set this if icon is not square (default: 13) - scale: 1 // Set badge scale (default: 1) -}) -``` - -Available color names: - -![](https://badgen.net/badge/color/blue/blue) -![](https://badgen.net/badge/color/cyan/cyan) -![](https://badgen.net/badge/color/green/green) -![](https://badgen.net/badge/color/yellow/yellow) -![](https://badgen.net/badge/color/orange/orange) -![](https://badgen.net/badge/color/red/red) -![](https://badgen.net/badge/color/pink/pink) -![](https://badgen.net/badge/color/purple/purple) -![](https://badgen.net/badge/color/grey/grey) -![](https://badgen.net/badge/color/black/black) - -### In browser - -```html - - -``` - -## Benchmarks - -`npm run bench` on iMac 5K (Late 2014), 3.5G i5, with Node.js 12.11.0: - -```bash -[classic] style, long params x 985,898 ops/sec ±0.37% (94 runs sampled) -[classic] style, full params x 1,284,886 ops/sec ±0.42% (95 runs sampled) -[classic] style, with emoji x 1,291,768 ops/sec ±0.28% (95 runs sampled) -[classic] style, with icon x 1,177,120 ops/sec ±0.94% (95 runs sampled) - [flat] style, long params x 780,504 ops/sec ±0.39% (94 runs sampled) - [flat] style, full params x 1,012,111 ops/sec ±0.40% (97 runs sampled) - [flat] style, with emoji x 1,013,695 ops/sec ±0.91% (95 runs sampled) - [flat] style, with icon x 994,481 ops/sec ±0.30% (94 runs sampled) -``` - -## See Also - -- [gradient-badge][gradient-badge] - Badge generator with color gradient support - -[npm-src]: https://badgen.net/npm/v/badgen -[npm-href]: https://www.npmjs.com/package/badgen -[bundlephobia-src]: https://badgen.net/bundlephobia/minzip/badgen -[bundlephobia-href]: https://bundlephobia.com/result?p=badgen -[coveralls-src]: https://badgen.net/coveralls/c/github/amio/badgen/master -[coveralls-href]: https://coveralls.io/github/amio/badgen?branch=master -[license-src]: https://badgen.net/github/license/amio/badgen -[license-href]: LICENSE.md -[gradient-badge]: https://github.com/bokub/gradient-badge diff --git a/node_modules/badgen/dist/calc-text-width.d.ts b/node_modules/badgen/dist/calc-text-width.d.ts deleted file mode 100644 index 9a7f69b85..000000000 --- a/node_modules/badgen/dist/calc-text-width.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare const Verdana110: ([...text]: Iterable) => number; diff --git a/node_modules/badgen/dist/color-presets.d.ts b/node_modules/badgen/dist/color-presets.d.ts deleted file mode 100644 index 99e17d67e..000000000 --- a/node_modules/badgen/dist/color-presets.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -declare const _default: { - green: string; - blue: string; - red: string; - yellow: string; - orange: string; - purple: string; - pink: string; - grey: string; - gray: string; - cyan: string; - black: string; -}; -export default _default; diff --git a/node_modules/badgen/dist/index.d.ts b/node_modules/badgen/dist/index.d.ts deleted file mode 100644 index cedecfe7f..000000000 --- a/node_modules/badgen/dist/index.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -export { Verdana110 as calcWidth } from './calc-text-width'; -declare type StyleOption = 'flat' | 'classic'; -interface BadgenOptions { - status: string; - subject?: string; - color?: string; - label?: string; - labelColor?: string; - style?: StyleOption; - icon?: string; - iconWidth?: number; - scale?: number; -} -export declare function badgen({ label, subject, status, color, style, icon, iconWidth, labelColor, scale }: BadgenOptions): string; -declare global { - interface Window { - badgen: typeof badgen; - } -} diff --git a/node_modules/badgen/dist/index.js b/node_modules/badgen/dist/index.js deleted file mode 100644 index fc75e396b..000000000 --- a/node_modules/badgen/dist/index.js +++ /dev/null @@ -1,2 +0,0 @@ -module.exports=function(t,e){"use strict";var n={};function __webpack_require__(e){if(n[e]){return n[e].exports}var i=n[e]={i:e,l:false,exports:{}};t[e].call(i.exports,i,i.exports,__webpack_require__);i.l=true;return i.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(325)}return startup()}({183:function(t,e){"use strict";Object.defineProperty(e,"__esModule",{value:true});e.default={green:"3C1",blue:"08C",red:"E43",yellow:"DB1",orange:"F73",purple:"94E",pink:"E5B",grey:"999",gray:"999",cyan:"1BC",black:"2A2A2A"}},261:function(t){t.exports=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39,43,50,90,70,120,80,30,50,50,70,90,40,50,40,50,70,70,70,70,70,70,70,70,70,70,50,50,90,90,90,60,110,75,75,77,85,70,63,85,83,46,50,76,61,93,82,87,66,87,76,75,68,81,75,110,75,68,75,50,50,50,90,70,70,66,69,57,69,66,39,69,70,30,38,65,30,110,70,67,69,69,47,57,43,70,65,90,65,65,58,70,50,70,90,0,61,110,110,110,110,110,110,110,110,110,110,110,110,110,55,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,55,110,39,43,70,70,70,70,50,70,70,110,60,71,90,0,110,70,60,90,60,60,70,71,70,40,70,60,60,71,110,110,110,60,75,75,75,75,75,75,110,77,70,70,70,70,46,46,46,46,85,82,87,87,87,87,87,90,87,81,81,81,81,68,67,68,66,66,66,66,66,66,110,57,66,66,66,66,30,30,30,30,67,70,67,67,67,67,67,90,67,70,70,70,70,65,69,65,75,66,75,66,75,66,77,57,77,57,77,57,77,57,85,71,85,69,70,66,70,66,70,66,70,66,70,66,85,69,85,69,85,69,85,69,83,70,83,70,46,30,46,30,46,30,46,30,46,30,96,68,50,38,76,65,65,61,30,61,30,61,33,61,50,62,31,82,70,82,70,82,70,80,82,70,87,67,87,67,87,67,120,110,76,47,76,47,76,47,75,57,75,57,75,57,75,57,68,43,68,43,68,43,81,70,81,70,81,69,81,70,81,70,81,69,110,90,68,65,68,75,58,75,58,75,58,33,69,77,64,69,75,62,76,76,59,83,96,64,69,65,60,83,58,59,70,79,72,100,43,43,73,64,42,65,120,81,68,86,89,67,120,98,74,69,70,59,56,65,58,41,74,41,70,83,73,86,78,68,74,67,63,61,61,56,57,70,70,52,50,67,29,48,50,32,140,140,130,94,90,61,110,110,99,76,61,32,32,85,68,76,68,76,68,81,70,76,68,81,70,61,76,61,76,61,100,94,88,69,79,69,72,64,85,68,85,68,61,56,28,140,140,130,85,69,110,61,82,70,75,66,110,110,87,67,72,60,76,61,63,58,60,61,30,27,32,32,76,63,85,68,68,37,70,45,71,61,76,68,75,57,68,43,58,55,81,68,81,100,85,68,67,63,76,61,60,61,85,68,85,68,85,68,85,68,69,57,63,100,63,28,100,100,75,81,56,62,68,55,55,62,62,81,95,75,75,62,61,25,96,69,87,44,86,69,61,69,69,69,56,61,70,70,61,66,86,51,51,71,64,45,70,69,65,59,65,68,68,68,42,41,45,56,53,33,72,100,100,100,69,70,69,68,89,86,84,45,45,47,45,45,45,45,61,61,56,47,48,53,59,41,41,72,73,68,57,85,57,53,63,77,56,59,49,49,49,53,85,58,65,67,69,53,64,51,70,50,49,110,110,130,88,78,96,110,74,77,68,64,71,71,40,40,26,27,27,35,35,51,36,26,52,35,22,28,29,29,31,31,38,39,40,40,70,70,20,70,31,31,20,40,31,31,42,42,31,31,50,50,50,50,70,70,70,70,70,70,23,38,41,20,35,40,31,43,43,43,43,43,42,42,37,46,48,24,24,26,26,32,31,47,47,41,27,31,31,31,31,42,42,50,0,0,53,0,51,68,52,39,49,0,46,51,53,38,47,0,52,52,39,39,39,11,46,47,44,44,26,17,41,48,48,48,48,25,25,0,49,46,21,40,41,38,40,57,53,53,52,52,52,51,68,68,62,62,68,62,79,41,0,40,57,48,41,68,0,0,52,42,53,38,40,51,47,45,52,52,52,57,44,0,45,41,52,48,45,45,56,41,20,48,51,47,83,52,51,51,51,51,51,45,44,36,45,44,44,45,44,51,40,41,45,45,46,37,65,51,32,32,79,64,79,79,68,56,56,56,50,66,79,79,79,79,70,70,75,50,83,96,59,79,97,79,83,100,30,75,75,62,77,70,75,83,87,46,76,75,93,82,71,87,83,66,79,74,68,68,90,75,96,90,46,68,69,56,70,30,69,69,68,65,67,56,50,70,69,30,65,65,70,65,55,67,70,69,56,69,55,69,87,65,90,89,30,69,67,69,89,62,57,64,59,59,70,85,86,61,85,68,73,59,59,56,60,56,73,88,98,92,74,61,74,55,73,73,67,66,81,61,51,45,61,67,56,33,86,58,58,63,67,76,95,80,78,81,81,81,70,70,87,62,77,75,46,46,50,120,120,90,76,83,68,83,75,75,75,62,82,70,110,68,83,83,76,81,93,83,87,83,66,77,68,68,90,75,84,78,110,110,86,100,75,77,110,78,66,68,65,52,68,66,88,58,70,70,65,68,77,70,67,70,69,59,55,65,92,65,71,67,96,98,70,87,63,60,92,66,66,66,70,52,60,57,30,30,38,100,100,70,65,70,65,70,97,85,69,60,99,82,66,59,97,83,94,81,120,110,57,53,76,77,75,63,69,55,69,55,130,110,75,62,96,84,97,85,71,59,69,0,0,0,0,0,0,0,78,63,69,60,70,62,62,52,62,52,67,55,110,88,65,56,76,65,76,65,72,57,90,76,83,70,110,78,110,96,82,66,72,58,66,53,68,65,68,65,75,65,99,74,75,60,78,67,78,70,85,65,85,65,30,100,84,69,60,78,64,78,62,78,63,75,60,96,82,30,72,60,72,60,100,93,63,58,83,66,76,58,100,84,65,56,64,64,78,63,78,63,76,63,87,67,75,63,74,59,69,52,69,52,69,52,75,60,61,46,95,85,65,45,69,55,69,55,68,62,90,95,87,71,59,55,110,89,110,91,68,57,78,70,74,59,78,64,84,76,91,75,110,81,85,68,100,87,75,69,110,88,120,100,76,66,74,68,49,44,98,89,62,58,73,65,79,84,63,81,81,68,71,63,60,80,75,64,57,80,72,66,65,77,79,68,80,61,81,70,59,66,73,67,81,68,81,61,54,63,69,75,69,64,77,79,79,44,37,33,42,29,38,0,79,82,56,67,70,55,58,52,56,63,63,55,30,84,58,54,55,51,57,58,58,30,56,48,58,45,81,48,67,58,58,83,70,56,43,81,65,55,69,59,79,39,44,79,79,79,79,88,79,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,3.3,15,0,0,0,38,0,28,0,0,28,0,5,44,12,79,79,79,79,79,79,79,79,71,62,47,55,78,35,37,78,71,35,58,63,59,77,76,34,45,73,66,58,63,53,63,73,56,79,76,79,79,79,79,79,68,68,66,31,53,79,79,79,79,79,79,79,79,79,79,79,97,190,93,81,290,120,71,71,86,58,58,53,32,49,93,58,0,0,.9,0,0,0,0,0,0,0,9,32,0,79,27,39,89,35,32,32,43,32,70,32,70,39,70,70,64,64,64,45,45,45,45,100,100,120,120,66,66,64,64,77,77,70,70,70,22,86,60,60,52,45,59,39,43,70,70,0,.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58,58,58,58,58,58,58,58,58,58,58,58,58,57,70,60,0,32,32,32,0,47,58,54,70,70,70,70,70,70,70,70,70,64,64,64,64,64,64,64,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,100,100,100,120,120,66,64,86,86,86,86,86,86,60,60,77,77,77,60,60,60,77,77,77,77,77,77,52,52,52,52,59,59,59,59,59,57,64,39,49,49,49,43,43,43,43,43,43,43,43,70,79,70,43,70,70,64,64,35,39,7,4.1,.45,.099,0,0,0,95,61,0,0,0,0,24,0,25,38,0,0,70,0,0,0,0,45,45,51,51,58,58,58,58,58,58,58,58,100,120,64,51,48,57,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,70,70,70,70,70,70,70,64,64,45,45,45,100,64,64,64,86,86,77,77,77,45,45,59,59,59,52,45,45,100,64,64,100,45,64,32,32,70,70,70,43,43,64,64,64,100,100,60,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,96,96,74,84,100,74,70,54,83,83,61,47,64,26,52,120,92,52,37,73,88,79,96,96,96,38,83,100,74,66,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,58,40,41,34,33,79,79,79,79,79,79,56,62,79,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,79,0,0,0,0,0,73,73,73,100,80,80,110,58,58,52,74,91,79,60,60,60,60,110,110,110,110,85,87,61,70,68,71,75,82,85,77,55,63,60,58,83,61,71,58,70,56,56,62,87,62,64,64,67,44,45,78,81,81,60,79,63,75,56,73,100,73,54,100,100,100,73,73,73,73,73,73,73,73,100,100,100,100,73,100,100,130,0,0,73,73,73,73,73,85,87,61,82,60,58,87,67,91,79,73,73,52,82,51,53,54,54,56,59,58,72,53,52,55,34,80,80,110,110,80,80,57,82,67,61,80,50,61,62,62,73,120,120,79,98,130,54,72,73,75,83,68,79,79,78,83,79,79,66,78,76,72,70,69,76,58,65,88,85,100,60,60,73,60,67,75,74,60,67,69,79,72,83,60,79,64,62,60,79,81,79,79,79,77,62,72,54,79,79,73,51,100,100,100,73,73,73,73,79,79,100,100,79,79,130,130,73,57,79,79,79,79,79,79,79,79,100,79,79,79,79,73,60,79,62,83,68,73,73,79,79,65,58,53,80,55,67,70,62,76,69,61,60,46,66,44,75,70,30,62,58,70,30,79,79,79,79,79,34,23,32,79,89,110,97,98,78,78,79,79,79,79,73,89,79,79,78,89,76,76,90,92,75,76,79,76,79,73,73,79,75,76,78,75,76,76,76,79,79,76,75,77,75,75,91,73,79,78,78,79,76,75,79,75,73,79,79,12,79,26,23,50,64,64,79,79,79,79,62,62,79,79,67,58,19,79,79,79,19,79,79,79,79,79,79,79,76,90,76,75,79,75,79,79,79,79,79,79,79,93,68,69,70,77,76,70,70,80,77,36,26,73,78,170,46,79,79,79,79,79,79,79,79,79,79,79,89,89,28,79,94,120,71,78,82,95,88,83,94,79,94,94,120,79,120,120,63,84,79,70,65,74,86,92,92,76,70,79,63,76,98,71,74,63,71,73,79,74,63,85,89,67,74,56,79,74,90,79,74,79,74,81,65,79,79,89,56,120,100,120,89,89,89,89,89,79,89,89,120,79,120,120,89,79,79,120,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,95,83,89,89,79,79,74,46,56,62,72,74,57,85,59,75,47,100,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,28,46,48,79,84,100,88,90,91,90,90,62,79,79,70,91,79,79,75,95,87,84,84,84,94,83,70,87,84,79,84,85,84,84,79,84,74,85,73,79,79,75,94,85,88,75,82,87,79,87,87,79,85,80,75,75,85,79,79,4.7,50,98,78,98,78,78,78,78,79,79,140,140,79,79,150,150,78,79,79,79,79,79,79,79,79,78,98,79,79,79,79,84,84,79,90,89,64,78,78,79,79,67,56,56,91,69,59,70,62,55,61,81,63,19,44,70,57,81,91,79,79,79,79,79,79,79,79,79,79,62,76,79,98,120,100,69,100,120,79,79,79,78,78,86,79,83,83,170,78,79,79,79,91,71,79,83,79,100,85,79,79,79,140,75,79,79,79,74,100,64,79,79,79,73,76,59,70,88,93,73,80,100,100,110,130,79,79,79,79,120,80,64,110,120,79,79,79,140,130,160,79,190,180,230,62,79,79,92,79,79,79,79,79,79,150,79,79,79,79,79,79,79,79,79,79,79,79,36,55,59,69,69,65,66,81,91,70,95,90,78,76,85,91,80,160,81,130,140,81,110,79,79,79,79,79,73,110,140,110,79,97,94,85,110,99,130,160,110,79,84,84,89,79,83,83,85,57,99,66,120,85,88,88,84,140,110,93,68,90,90,92,90,90,90,90,84,79,84,84,90,90,120,140,68,97,85,71,97,84,61,84,84,120,79,79,79,70,110,73,73,110,140,120,150,79,73,73,73,79,73,73,110,73,79,79,79,79,79,79,79,73,73,79,88,84,90,79,79,79,79,79,200,150,73,73,79,79,64,62,77,55,65,71,50,57,65,50,79,79,79,79,79,79,79,79,58,28,52,82,74,74,73,86,42,61,120,93,79,90,85,92,120,120,140,120,110,79,81,81,84,79,81,81,84,68,94,70,87,81,81,95,81,140,120,85,73,82,82,85,81,88,88,88,80,79,81,81,86,86,120,140,73,90,90,83,79,83,72,81,83,87,79,79,61,52,120,71,110,100,130,89,130,79,74,110,120,79,140,180,110,110,79,79,79,79,79,79,79,97,89,79,79,79,79,79,79,79,90,79,150,150,69,80,79,79,72,67,85,83,83,92,85,82,99,67,79,59,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,42,31,79,140,150,99,180,70,150,88,110,79,120,120,180,79,70,120,150,97,88,83,130,110,91,130,88,160,140,57,64,120,120,140,96,81,61,92,92,100,78,110,130,64,64,97,67,63,84,72,63,88,94,110,120,120,81,79,79,42,110,89,88,96,96,100,100,79,130,120,180,79,170,160,200,66,19,79,79,79,79,79,79,79,79,150,79,79,79,79,79,79,79,79,88,120,70,81,79,79,64,86,88,110,68,97,130,48,88,100,92,96,130,76,82,110,79,79,79,120,150,100,68,110,94,110,79,79,68,48,79,91,130,130,130,92,90,95,150,150,200,110,170,100,110,160,100,100,170,79,79,79,120,110,100,94,110,120,100,90,88,180,170,150,100,95,100,110,100,140,130,110,96,83,110,100,79,100,88,100,110,120,110,100,99,88,79,99,79,79,97,110,88,100,120,110,100,79,79,79,86,79,79,79,79,120,130,130,89,89,89,79,89,79,140,160,160,220,190,190,220,150,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,200,63,160,79,79,79,79,79,79,79,79,79,79,79,21,66,63,63,70,69,70,52,58,67,64,65,90,90,73,73,59,76,94,90,69,69,66,69,61,68,72,72,65,65,74,74,73,69,67,53,66,64,73,56,69,71,66,69,74,64,63,68,48,56,56,110,56,56,56,56,56,56,56,79,79,79,79,75,35,64,56,61,46,57,67,56,56,56,56,56,56,56,56,81,64,68,72,75,68,66,64,84,68,73,85,140,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,68,60,79,62,79,79,56,61,79,60,79,79,62,79,79,79,79,79,79,64,66,69,71,79,68,58,58,74,73,73,74,79,68,61,60,79,61,79,59,79,79,61,84,79,61,61,58,56,0,47,47,0,0,0,0,0,0,79,0,0,54,79,79,38,65,37,37,37,79,65,79,0,0,0,0,36,0,79,79,61,56,55,63,56,58,69,69,73,69,79,79,110,110,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,69,54,85,85,130,66,130,160,42,63,71,18,18,27,50,27,27,34,120,65,40,71,52,83,45,37,32,55,55,34,55,58,38,38,60,57,76,55,63,63,52,56,56,60,57,76,55,63,63,56,56,55,58,41,55,33,60,6.3,150,150,54,54,31,47,57,57,57,56,52,59,57,52,79,51,52,52,52,56,52,52,52,52,56,52,57,57,57,56,57,59,57,52,56,52,52,54,52,62,54,59,57,57,57,52,66,56,54,58,58,79,79,79,79,60,55,60,61,120,56,120,56,120,53,54,57,57,22,51,54,60,41,41,15,57,41,37,0,58,52,58,79,79,79,79,56,56,56,56,56,56,56,56,79,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,59,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,79,56,56,64,43,54,65,45,36,50,71,39,61,66,64,68,79,70,55,220,52,23,130,53,70,72,67,70,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,120,66,68,120,66,68,120,66,84,110,120,75,66,75,68,130,120,120,63,68,69,68,68,68,120,68,120,67,120,68,120,120,66,110,79,120,130,66,66,65,79,130,240,79,120,65,65,65,65,120,65,79,79,79,65,65,90,68,65,76,81,65,65,170,68,66,66,66,66,66,68,68,68,68,23,43,66,81,66,97,68,68,68,68,66,94,120,170,65,65,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,73,74,78,77,67,87,73,86,62,70,86,77,69,75,78,76,81,68,65,75,75,78,71,69,69,69,70,85,65,73,69,74,81,63,67,67,74,87,79,79,79,79,79,79,79,79,79,79,51,63,64,100,56,60,80,110,65,53,130,55,56,95,57,59,91,54,85,92,86,56,88,51,58,53,62,56,56,63,55,87,52,74,63,60,54,60,93,66,66,66,66,59,66,79,79,79,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,79,79,79,79,79,0,0,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,95,110,110,110,95,79,79,79,79,79,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,79,79,79,79,79,79,76,99,71,73,72,80,99,120,71,91,91,71,94,81,120,95,110,130,130,110,130,110,110,130,120,150,130,120,130,120,120,130,110,130,110,110,110,120,110,110,67,78,76,99,92,68,90,99,74,97,97,74,96,74,74,97,84,100,100,84,100,88,84,100,94,94,94,94,94,94,94,94,110,79,130,94,94,130,79,79,97,97,97,97,97,110,97,79,110,79,140,97,97,120,79,79,78,99,99,78,98,100,78,99,84,100,100,84,100,100,84,100,85,85,85,86,86,85,85,85,85,86,85,86,85,100,87,85,76,95,90,76,89,74,110,110,110,79,110,83,89,110,79,79,58,77,72,70,71,75,87,81,83,96,91,83,89,83,100,86,70,95,95,70,94,72,71,87,79,100,100,79,100,79,79,99,120,79,110,95,100,110,79,79,98,120,120,98,120,98,98,79,140,79,130,120,120,130,79,79,100,120,100,100,100,130,100,130,74,98,95,72,95,72,78,79,82,100,100,82,100,99,82,100,120,120,120,120,120,140,120,120,64,80,91,65,100,77,90,110,84,110,110,82,100,93,91,110,84,110,100,78,100,99,91,100,85,110,110,84,110,100,92,110,64,92,67,70,66,88,64,79,110,79,100,69,81,100,79,79,81,100,81,81,81,97,87,81,120,140,140,120,140,120,120,140,150,150,150,150,180,150,150,150,73,97,95,72,95,93,74,95,76,98,97,73,96,95,77,95,74,98,76,67,76,72,77,91,94,95,100,95,110,92,94,92,85,86,85,86,85,85,85,85,89,130,100,79,79,79,79,78,100,33,68,39,39,39,55,33,100,61,56,59,60,72,66,67,71,62,46,82,82,96,60,71,87,90,58,62,110,79,79,79,170,160,130,170,120,110,98,140,110,110,120,140,110,97,86,120,32,60,32,32,60,76,51,99,110,56,79,79,79,79,79,79,81,74,71,77,110,41,70,80,59,69,81,54,66,100,68,97,50,62,120,100,70,66,80,99,57,91,90,91,68,78,83,59,83,100,73,63,68,88,72,130,89,100,110,57,87,120,63,71,56,72,74,54,100,63,76,84,84,81,58,92,78,67,67,76,73,95,62,76,91,80,80,71,86,90,120,83,94,63,63,130,74,88,73,88,68,79,79,79,56,67,46,74,50,79,79,79,79,87,87,87,87,82,82,82,82,82,82,82,88,88,88,88,88,88,97,100,97,100,82,100,97,100,97,82,73,65,54,35,35,50,50,38,53,55,35,23,44,45,44,120,98,110,120,91,91,91,91,84,84,84,84,84,84,84,92,92,92,94,92,91,95,100,95,100,100,95,100,95,84,46,15,40,90,90,90,90,77,77,77,77,77,77,77,110,100,100,110,100,110,91,92,91,92,92,91,92,91,93,38,110,110,96,96,69,69,69,69,69,69,69,69,69,84,84,81,87,81,87,84,84,84,84,84,84,84,84,84,43,43,85,88,87,87,72,72,72,72,72,72,72,72,72,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,41,41,71,68,68,68,68,68,68,68,68,80,86,84,77,84,77,77,84,77,84,84,77,84,77,82,38,38,38,47,67,100,100,100,100,100,100,100,100,100,120,120,120,100,120,100,100,60,50,60,96,96,96,96,96,96,96,96,96,110,110,110,110,110,110,96,110,96,110,110,97,110,97,55,49,74,65,65,65,65,65,65,65,65,65,77,80,80,77,81,77,70,85,70,85,81,83,86,78,80,39,45,39,55,39,39,39,120,120,110,110,95,95,95,75,75,75,75,110,110,110,110,110,110,90,90,90,90,90,90,90,90,57,64,64,64,64,64,64,64,64,64,79,79,79,79,79,79,82,79,82,79,79,79,79,79,79,38,51,37,37,100,100,100,100,100,100,68,68,68,68,68,68,83,83,40,49,74,89,89,89,89,94,94,94,94,110,110,54,92,92,92,92,92,92,82,82,82,82,98,98,50,90,90,77,77,66,90,90,77,77,86,86,86,84,84,84,84,54,78,37,110,110,110,110,110,110,110,82,69,69,69,69,89,89,89,89,130,130,130,110,110,130,130,60,93,69,69,69,69,100,100,100,100,60,96,96,96,96,96,96,55,64,64,64,64,64,64,64,38,63,56,56,56,56,63,63,63,63,80,80,80,80,80,80,80,80,80,80,80,80,91,91,83,83,83,83,91,91,83,83,83,83,91,91,84,84,84,84,91,91,84,84,84,84,88,88,75,75,75,75,88,88,71,71,71,71,90,90,76,76,76,76,44,110,110,62,62,62,62,110,110,73,73,73,73,110,110,73,73,73,73,52,72,72,98,98,98,98,110,110,62,62,62,62,90,90,75,75,75,75,70,70,70,100,100,100,100,100,74,74,100,100,100,100,100,100,69,69,69,69,100,100,71,71,71,71,96,96,69,68,68,69,110,110,70,70,70,70,130,130,64,64,64,64,84,84,76,76,76,76,45,45,84,84,76,76,76,76,110,110,62,62,62,62,110,110,68,68,68,68,41,110,110,70,70,70,70,110,110,62,62,62,62,110,110,70,70,70,70,69,53,110,160,160,170,140,140,160,160,79,79,79,79,79,79,79,79,79,54,54,76,98,120,140,54,76,98,120,140,54,76,98,120,140,54,76,98,120,140,81,140,110,120,140,98,81,81,79,79,79,67,67,52,52,52,63,53,53,43,55,55,59,69,45,45,69,67,55,50,65,65,65,70,69,69,53,41,41,71,30,71,45,71,20,30,82,84,71,45,71,64,79,59,41,20,32,67,67,43,50,53,45,53,45,65,65,56,32,43,50,66,54,67,65,110,71,110,79,69,65,56,20,67,53,62,32,32,62,69,56,48,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,66,66,66,100,66,66,66,66,140,100,66,66,66,100,140,66,66,68,66,66,66,66,66,66,66,100,39,100,39,66,66,100,100,110,64,66,100,66,100,66,66,78,68,66,66,66,66,66,66,66,66,66,0,0,94,61,61,61,61,52,52,52,99,110,110,91,91,98,130,140,52,87,79,52,66,52,52,53,52,52,52,52,52,52,51,68,38,58,200,71,130,42,58,54,79,79,58,58,73,97,65,65,65,77,65,62,79,79,79,79,79,79,41,45,18,72,45,44,31,59,31,49,79,79,79,79,79,79,62,24,32,33,42,61,20,33,36,37,20,0,0,0,0,110,58,69,54,47,62,47,61,57,57,63,110,110,110,110,110,110,69,66,53,47,47,47,52,54,59,43,51,52,50,70,58,61,47,56,43,42,41,42,40,43,39,61,49,53,44,47,53,60,71,44,35,32,47,52,50,63,49,50,56,57,50,57,58,55,48,42,47,49,39,41,41,46,49,44,61,54,48,67,40,45,51,42,57,82,48,48,50,48,48,45,42,55,61,62,57,49,50,56,59,42,84,43,51,57,110,110,110,110,110,110,110,110,49,35,54,58,57,42,64,44,52,51,58,46,45,37,45,40,42,42,53,60,63,55,47,49,42,54,48,46,63,51,56,58,56,47,67,52,63,62,32,45,51,66,110,110,110,110,110,110,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,71,58,73,97,65,65,65,77,65,62,140,140,140,160,140,140,70,58,73,97,65,65,65,77,65,62,140,140,140,160,140,140,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,62,77,93,64,64,70,72,57,52,32,37,62,52,80,69,73,64,73,73,74,100,68,66,66,56,62,62,54,68,74,92,74,61,85,63,57,48,64,54,57,69,56,63,65,35,48,33,39,40,31,31,37,39,19,24,35,29,45,38,38,42,40,32,35,33,38,44,39,39,40,57,40,40,36,36,31,31,40,21,38,60,40,40,33,40,40,40,27,40,44,60,35,40,40,39,39,54,40,21,28,41,36,40,40,39,55,38,100,68,70,40,92,61,69,44,40,55,40,55,61,42,61,98,24,24,61,60,63,61,61,31,78,55,24,92,61,61,37,55,43,55,55,55,61,61,61,61,50,50,72,24,55,24,61,60,41,39,38,41,35,25,25,41,42,17,17,17,17,30,17,17,30,63,63,42,42,42,42,41,37,17,24,42,43,42,39,35,39,39,39,41,43,52,52,0,0,52,52,52,52,56,56,38,57,57,48,41,43,79,79,79,60,58,59,53,46,48,48,79,44,46,33,42,47,45,44,43,47,45,42,45,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,0,0,72,60,63,69,75,69,63,69,77,57,82,69,85,69,82,69,82,69,82,69,70,66,70,66,60,61,60,61,60,61,59,40,79,69,81,68,83,70,81,68,81,68,81,68,32,32,46,30,76,65,76,65,72,64,61,30,59,32,59,32,59,32,93,110,95,100,93,110,81,68,82,70,81,68,81,68,87,67,85,68,87,67,87,67,66,69,61,69,70,45,76,47,70,45,70,45,59,56,75,57,59,56,59,56,59,56,70,41,68,43,70,41,70,41,76,68,76,68,76,68,81,70,76,68,75,65,75,65,110,90,110,90,110,90,94,85,110,90,69,67,69,67,69,57,67,63,75,58,67,63,68,41,85,57,61,36,47,46,92,55,75,66,75,66,75,66,75,66,75,66,75,66,75,66,75,66,75,66,75,66,75,66,75,66,70,66,70,66,70,66,70,66,70,66,70,66,70,66,70,66,46,30,46,30,87,67,87,67,87,67,87,67,87,67,87,67,87,67,89,67,89,67,89,67,89,67,89,67,81,70,81,70,83,73,83,73,83,73,83,73,83,73,68,65,68,65,68,65,68,65,100,65,56,49,50,50,76,76,76,76,76,76,76,76,76,79,100,100,97,98,86,84,52,52,52,52,52,52,79,79,79,79,100,100,100,100,79,79,68,68,68,68,68,68,68,68,100,100,120,120,120,120,110,100,40,40,40,40,40,40,40,40,51,51,73,75,73,74,60,56,68,68,68,68,68,68,79,79,100,100,130,130,120,76,79,79,66,66,66,66,66,66,66,66,79,96,79,120,79,120,79,100,99,99,99,99,99,99,99,99,100,110,130,130,120,120,110,110,69,69,56,56,70,70,30,30,67,67,69,69,89,89,79,79,76,76,76,76,76,76,76,76,120,120,140,140,140,140,130,120,68,68,68,68,68,68,68,68,140,140,160,160,160,160,150,150,99,99,99,99,99,99,99,99,140,150,170,170,160,160,150,150,76,76,76,76,76,79,76,76,76,76,75,75,120,68,30,68,68,68,68,68,68,79,68,68,70,83,83,96,120,68,68,68,40,40,30,30,79,79,40,40,32,32,46,59,79,68,68,68,66,66,69,69,67,67,66,66,70,70,68,83,80,70,70,70,79,79,99,99,99,79,99,99,87,97,90,100,130,70,68,79,55,110,55,110,37,28,18,70,40,22,6.9,0,0,0,0,0,64,64,70,70,110,110,65,70,30,30,30,30,50,50,50,50,70,70,60,52,37,52,90,35,0,0,0,0,0,0,0,19,170,150,40,61,61,36,60,83,39,50,50,79,69,46,70,55,55,51,100,36,40,36,36,89,78,78,70,70,60,60,53,35,55,53,61,110,55,77,65,110,65,65,110,65,77,110,31,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,24,79,79,60,60,46,60,60,46,46,46,46,25,25,60,46,46,46,46,46,46,46,46,46,46,46,46,46,25,25,79,31,31,31,28,31,66,66,66,66,66,66,66,66,79,79,79,70,77,77,70,70,110,82,130,130,110,92,69]},325:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:true});var i=n(363);e.calcWidth=i.Verdana110;const r=n(363);const s=n(183);function badgen({label:t,subject:e,status:n,color:i="blue",style:a,icon:l,iconWidth:o=13,labelColor:f="555",scale:x=1}){typeAssert(typeof n==="string"," must be string");t=t===undefined?e:t;if(!t&&!l){return bare({status:n,color:i,style:a})}i=s.default[i]||i;f=s.default[f]||f;o=o*10;const g=l?t.length?o+30:o-18:0;const c=l?g+50:50;const h=r.Verdana110(t);const u=r.Verdana110(n);const $=h+100+g;const d=u+100;const p=$+d;const w=l?' xmlns:xlink="http://www.w3.org/1999/xlink"':"";t=sanitize(t);n=sanitize(n);if(a==="flat"){return`\n \n \n \n \n \n ${t}\n ${t}\n ${n}\n ${n}\n \n ${l?``:""}\n`}return`\n \n \n \n \n \n \n \n \n \n \n \n ${t}\n ${t}\n ${n}\n ${n}\n \n ${l?``:""}\n`}e.badgen=badgen;function bare({status:t,color:e,style:n}){typeAssert(typeof t==="string"," must be string");e=s.default[e]||e||s.default.blue;const i=r.Verdana110(t);const a=i+115;t=sanitize(t);if(n==="flat"){return`\n \n \n \n \n ${t}\n ${t}\n \n`}return`\n \n \n \n \n \n \n \n \n \n \n ${t}\n ${t}\n \n`}function sanitize(t){return t.replace(/\u0026/g,"&").replace(/\u003C/g,"<")}function typeAssert(t,e){if(!t)throw new TypeError(e)}if(typeof window==="object"){window.badgen=badgen}},363:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:true});const i=n(261);const r=t=>{const e=t[64];return([...n])=>{let i=0;let r=0;let s=n.length;while(s--){r=t[n[s].charCodeAt()];i+=r===undefined?e:r}return i}};e.Verdana110=r(i)}}); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/badgen/dist/index.js.map b/node_modules/badgen/dist/index.js.map deleted file mode 100644 index 7559cfc26..000000000 --- a/node_modules/badgen/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -"{\"version\":3,\"sources\":[\"/webpack/bootstrap\",\"../src/color-presets.ts\",\"../src/index.ts\",\"../src/calc-text-width.ts\"],\"names\":[\"installedModules\",\"__webpack_require__\",\"moduleId\",\"exports\",\"module\",\"i\",\"l\",\"modules\",\"call\",\"ab\",\"__dirname\",\"startup\",\"default\",\"green\",\"blue\",\"red\",\"yellow\",\"orange\",\"purple\",\"pink\",\"grey\",\"gray\",\"cyan\",\"black\",\"calc_text_width_1\",\"calcWidth\",\"Verdana110\",\"calc_text_width_2\",\"color_presets_1\",\"badgen\",\"label\",\"subject\",\"status\",\"color\",\"style\",\"icon\",\"iconWidth\",\"labelColor\",\"scale\",\"typeAssert\",\"undefined\",\"bare\",\"iconSpanWidth\",\"length\",\"sbTextStart\",\"sbTextWidth\",\"stTextWidth\",\"sbRectWidth\",\"stRectWidth\",\"width\",\"xlink\",\"sanitize\",\"str\",\"replace\",\"assertion\",\"message\",\"TypeError\",\"window\",\"widthsVerdana110\",\"charWidthTable\",\"fallbackWidth\",\"text\",\"total\",\"charWidth\",\"charCodeAt\"],\"mappings\":\"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\",\"file\":\"index.js\",\"sourcesContent\":[\" \\t// The module cache\\n \\tvar installedModules = {};\\n\\n \\t// The require function\\n \\tfunction __webpack_require__(moduleId) {\\n\\n \\t\\t// Check if module is in cache\\n \\t\\tif(installedModules[moduleId]) {\\n \\t\\t\\treturn installedModules[moduleId].exports;\\n \\t\\t}\\n \\t\\t// Create a new module (and put it into the cache)\\n \\t\\tvar module = installedModules[moduleId] = {\\n \\t\\t\\ti: moduleId,\\n \\t\\t\\tl: false,\\n \\t\\t\\texports: {}\\n \\t\\t};\\n\\n \\t\\t// Execute the module function\\n \\t\\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\\n\\n \\t\\t// Flag the module as loaded\\n \\t\\tmodule.l = true;\\n\\n \\t\\t// Return the exports of the module\\n \\t\\treturn module.exports;\\n \\t}\\n\\n\\n \\t__webpack_require__.ab = __dirname + \\\"/\\\";\\n\\n \\t// the startup function\\n \\tfunction startup() {\\n \\t\\t// Load entry module and return exports\\n \\t\\treturn __webpack_require__(325);\\n \\t};\\n\\n \\t// run startup\\n \\treturn startup();\\n\",\"export default {\\n green: '3C1',\\n blue: '08C',\\n red: 'E43',\\n yellow: 'DB1',\\n orange: 'F73',\\n purple: '94E',\\n pink: 'E5B',\\n grey: '999',\\n gray: '999',\\n cyan: '1BC',\\n black: '2A2A2A'\\n}\\n\",\"export { Verdana110 as calcWidth } from './calc-text-width'\\nimport { Verdana110 as calcWidth } from './calc-text-width'\\nimport colorPresets from './color-presets'\\n\\ntype StyleOption = 'flat' | 'classic'\\n\\ninterface BadgenOptions {\\n status: string;\\n subject?: string;\\n color?: string;\\n label?: string;\\n labelColor?: string\\n style?: StyleOption;\\n icon?: string;\\n iconWidth?: number;\\n scale?: number\\n}\\n\\nexport function badgen ({\\n label,\\n subject,\\n status,\\n color = 'blue',\\n style,\\n icon,\\n iconWidth = 13,\\n labelColor = '555',\\n scale = 1\\n}: BadgenOptions) {\\n typeAssert(typeof status === 'string', ' must be string')\\n\\n label = label === undefined ? subject : label // subject is deprecated\\n if (!label && !icon) {\\n return bare({ status, color, style })\\n }\\n\\n color = colorPresets[color] || color\\n labelColor = colorPresets[labelColor] || labelColor\\n iconWidth = iconWidth * 10\\n\\n const iconSpanWidth = icon ? (label.length ? iconWidth + 30 : iconWidth - 18) : 0\\n const sbTextStart = icon ? (iconSpanWidth + 50) : 50\\n const sbTextWidth = calcWidth(label)\\n const stTextWidth = calcWidth(status)\\n const sbRectWidth = sbTextWidth + 100 + iconSpanWidth\\n const stRectWidth = stTextWidth + 100\\n const width = sbRectWidth + stRectWidth\\n const xlink = icon ? ' xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\"' : ''\\n\\n label = sanitize(label)\\n status = sanitize(status)\\n\\n if (style === 'flat') {\\n return `\\n \\n \\n \\n \\n \\n ${label}\\n ${label}\\n ${status}\\n ${status}\\n \\n ${icon ? `` : ''}\\n`\\n }\\n\\n return `\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ${label}\\n ${label}\\n ${status}\\n ${status}\\n \\n ${icon ? `` : ''}\\n`\\n}\\n\\nfunction bare ({ status, color, style }) {\\n typeAssert(typeof status === 'string', ' must be string')\\n color = colorPresets[color] || color || colorPresets.blue\\n\\n const stTextWidth = calcWidth(status)\\n const stRectWidth = stTextWidth + 115\\n\\n status = sanitize(status)\\n\\n if (style === 'flat') {\\n return `\\n \\n \\n \\n \\n ${status}\\n ${status}\\n \\n`\\n }\\n\\n return `\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n ${status}\\n ${status}\\n \\n`\\n}\\n\\nfunction sanitize (str: string): string {\\n return str.replace(/\\\\u0026/g, '&').replace(/\\\\u003C/g, '<')\\n}\\n\\nfunction typeAssert (assertion: boolean, message: string): void {\\n if (!assertion) throw new TypeError(message)\\n}\\n\\ndeclare global {\\n interface Window {\\n badgen: typeof badgen;\\n }\\n}\\n\\nif (typeof window === 'object') {\\n window.badgen = badgen\\n}\\n\",\"// import widthsVerdana110 from './widths-verdana-110.json'\\n// @ts-ignore\\nconst widthsVerdana110 = require('./widths-verdana-110.json')\\n\\nconst calcWidth = (charWidthTable) => {\\n const fallbackWidth = charWidthTable[64] // Width as \\\"@\\\" for overflows\\n\\n return ([...text]) => {\\n let total = 0\\n let charWidth = 0\\n let i = text.length\\n while (i--) {\\n charWidth = charWidthTable[text[i].charCodeAt()]\\n total += charWidth === undefined ? fallbackWidth : charWidth\\n }\\n return total\\n }\\n}\\n\\nexport const Verdana110 = calcWidth(widthsVerdana110)\\n\"]}" \ No newline at end of file diff --git a/node_modules/badgen/package.json b/node_modules/badgen/package.json deleted file mode 100644 index cf85c49f4..000000000 --- a/node_modules/badgen/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "_from": "badgen@^3.0.1", - "_id": "badgen@3.0.1", - "_inBundle": false, - "_integrity": "sha512-ANQ8b2/zOvqLUMJ5fLgUCO7xRmOqFx9+ZOta9p3Taudd9c/gHEAh+5Ivnr2zFgj9kguTzXKkEzfI48hDwGWNcA==", - "_location": "/badgen", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "badgen@^3.0.1", - "name": "badgen", - "escapedName": "badgen", - "rawSpec": "^3.0.1", - "saveSpec": null, - "fetchSpec": "^3.0.1" - }, - "_requiredBy": [ - "#USER", - "/" - ], - "_resolved": "https://registry.npmjs.org/badgen/-/badgen-3.0.1.tgz", - "_shasum": "1d57d1241c61b0c9c19a502fda71ef0364ccf9c9", - "_spec": "badgen@^3.0.1", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge", - "author": { - "name": "Amio", - "email": "amio.cn@gmail.com" - }, - "bugs": { - "url": "https://github.com/amio/badgen/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Fast svg badge generator.", - "devDependencies": { - "@types/node": "^12.7.9", - "@zeit/ncc": "^0.20.5", - "benchmark": "^2.1.4", - "serve-marked": "^2.0.2", - "standard": "^14.3.1", - "tap": "^14.6.9", - "typescript": "^3.7.0-beta" - }, - "homepage": "https://github.com/amio/badgen#readme", - "license": "MIT", - "main": "dist/index.js", - "name": "badgen", - "repository": { - "type": "git", - "url": "git+https://github.com/amio/badgen.git" - }, - "scripts": { - "bench": "node bench/index.js", - "build": "ncc -s -m --no-source-map-register build src/index.ts", - "prebuild": "rm -rf dist", - "prepack": "npm run build", - "pretest": "npm run build", - "preview": "node preview/serve.js", - "snaptests": "TAP_SNAPSHOT=1 npm test", - "test": "tap test/*.spec.ts" - }, - "types": "dist/index.d.ts", - "version": "3.0.1" -} diff --git a/node_modules/badgen/tsconfig.json b/node_modules/badgen/tsconfig.json deleted file mode 100644 index d8f84418e..000000000 --- a/node_modules/badgen/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "target": "es2017", - "module": "commonjs", - "lib": ["esnext", "dom"], - - "rootDir": "src", - "outDir": "dist", - - "sourceMap":true, - "declaration": true, - - "resolveJsonModule": true, - "experimentalDecorators": true, - "allowSyntheticDefaultImports": true - }, - "include": ["src"] -} diff --git a/node_modules/balanced-match/.npmignore b/node_modules/balanced-match/.npmignore deleted file mode 100644 index ae5d8c36a..000000000 --- a/node_modules/balanced-match/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -test -.gitignore -.travis.yml -Makefile -example.js diff --git a/node_modules/balanced-match/LICENSE.md b/node_modules/balanced-match/LICENSE.md deleted file mode 100644 index 2cdc8e414..000000000 --- a/node_modules/balanced-match/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -(MIT) - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/node_modules/balanced-match/README.md b/node_modules/balanced-match/README.md deleted file mode 100644 index 08e918c0d..000000000 --- a/node_modules/balanced-match/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# balanced-match - -Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well! - -[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) -[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) - -[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) - -## Example - -Get the first matching pair of braces: - -```js -var balanced = require('balanced-match'); - -console.log(balanced('{', '}', 'pre{in{nested}}post')); -console.log(balanced('{', '}', 'pre{first}between{second}post')); -console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); -``` - -The matches are: - -```bash -$ node example.js -{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } -{ start: 3, - end: 9, - pre: 'pre', - body: 'first', - post: 'between{second}post' } -{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } -``` - -## API - -### var m = balanced(a, b, str) - -For the first non-nested matching pair of `a` and `b` in `str`, return an -object with those keys: - -* **start** the index of the first match of `a` -* **end** the index of the matching `b` -* **pre** the preamble, `a` and `b` not included -* **body** the match, `a` and `b` not included -* **post** the postscript, `a` and `b` not included - -If there's no match, `undefined` will be returned. - -If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. - -### var r = balanced.range(a, b, str) - -For the first non-nested matching pair of `a` and `b` in `str`, return an -array with indexes: `[ , ]`. - -If there's no match, `undefined` will be returned. - -If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. - -## Installation - -With [npm](https://npmjs.org) do: - -```bash -npm install balanced-match -``` - -## License - -(MIT) - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/node_modules/balanced-match/index.js b/node_modules/balanced-match/index.js deleted file mode 100644 index 1685a7629..000000000 --- a/node_modules/balanced-match/index.js +++ /dev/null @@ -1,59 +0,0 @@ -'use strict'; -module.exports = balanced; -function balanced(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); - - var r = range(a, b, str); - - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} - -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} - -balanced.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; - - if (ai >= 0 && bi > 0) { - begs = []; - left = str.length; - - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } - - bi = str.indexOf(b, i + 1); - } - - i = ai < bi && ai >= 0 ? ai : bi; - } - - if (begs.length) { - result = [ left, right ]; - } - } - - return result; -} diff --git a/node_modules/balanced-match/package.json b/node_modules/balanced-match/package.json deleted file mode 100644 index 49869f4f7..000000000 --- a/node_modules/balanced-match/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "_from": "balanced-match@^1.0.0", - "_id": "balanced-match@1.0.0", - "_inBundle": false, - "_integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "_location": "/balanced-match", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "balanced-match@^1.0.0", - "name": "balanced-match", - "escapedName": "balanced-match", - "rawSpec": "^1.0.0", - "saveSpec": null, - "fetchSpec": "^1.0.0" - }, - "_requiredBy": [ - "/brace-expansion" - ], - "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "_shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767", - "_spec": "balanced-match@^1.0.0", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\brace-expansion", - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "bugs": { - "url": "https://github.com/juliangruber/balanced-match/issues" - }, - "bundleDependencies": false, - "dependencies": {}, - "deprecated": false, - "description": "Match balanced character pairs, like \"{\" and \"}\"", - "devDependencies": { - "matcha": "^0.7.0", - "tape": "^4.6.0" - }, - "homepage": "https://github.com/juliangruber/balanced-match", - "keywords": [ - "match", - "regexp", - "test", - "balanced", - "parse" - ], - "license": "MIT", - "main": "index.js", - "name": "balanced-match", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/balanced-match.git" - }, - "scripts": { - "bench": "make bench", - "test": "make test" - }, - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/8..latest", - "firefox/20..latest", - "firefox/nightly", - "chrome/25..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - }, - "version": "1.0.0" -} diff --git a/node_modules/brace-expansion/LICENSE b/node_modules/brace-expansion/LICENSE deleted file mode 100644 index de3226673..000000000 --- a/node_modules/brace-expansion/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 Julian Gruber - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/node_modules/brace-expansion/README.md b/node_modules/brace-expansion/README.md deleted file mode 100644 index 6b4e0e164..000000000 --- a/node_modules/brace-expansion/README.md +++ /dev/null @@ -1,129 +0,0 @@ -# brace-expansion - -[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), -as known from sh/bash, in JavaScript. - -[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) -[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) -[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/) - -[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) - -## Example - -```js -var expand = require('brace-expansion'); - -expand('file-{a,b,c}.jpg') -// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] - -expand('-v{,,}') -// => ['-v', '-v', '-v'] - -expand('file{0..2}.jpg') -// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] - -expand('file-{a..c}.jpg') -// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] - -expand('file{2..0}.jpg') -// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] - -expand('file{0..4..2}.jpg') -// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] - -expand('file-{a..e..2}.jpg') -// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] - -expand('file{00..10..5}.jpg') -// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] - -expand('{{A..C},{a..c}}') -// => ['A', 'B', 'C', 'a', 'b', 'c'] - -expand('ppp{,config,oe{,conf}}') -// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] -``` - -## API - -```js -var expand = require('brace-expansion'); -``` - -### var expanded = expand(str) - -Return an array of all possible and valid expansions of `str`. If none are -found, `[str]` is returned. - -Valid expansions are: - -```js -/^(.*,)+(.+)?$/ -// {a,b,...} -``` - -A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. - -```js -/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ -// {x..y[..incr]} -``` - -A numeric sequence from `x` to `y` inclusive, with optional increment. -If `x` or `y` start with a leading `0`, all the numbers will be padded -to have equal length. Negative numbers and backwards iteration work too. - -```js -/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ -// {x..y[..incr]} -``` - -An alphabetic sequence from `x` to `y` inclusive, with optional increment. -`x` and `y` must be exactly one character, and if given, `incr` must be a -number. - -For compatibility reasons, the string `${` is not eligible for brace expansion. - -## Installation - -With [npm](https://npmjs.org) do: - -```bash -npm install brace-expansion -``` - -## Contributors - -- [Julian Gruber](https://github.com/juliangruber) -- [Isaac Z. Schlueter](https://github.com/isaacs) - -## Sponsors - -This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)! - -Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)! - -## License - -(MIT) - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/node_modules/brace-expansion/index.js b/node_modules/brace-expansion/index.js deleted file mode 100644 index 0478be81e..000000000 --- a/node_modules/brace-expansion/index.js +++ /dev/null @@ -1,201 +0,0 @@ -var concatMap = require('concat-map'); -var balanced = require('balanced-match'); - -module.exports = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function identity(e) { - return e; -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; - - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - - return expansions; -} - diff --git a/node_modules/brace-expansion/package.json b/node_modules/brace-expansion/package.json deleted file mode 100644 index d86159368..000000000 --- a/node_modules/brace-expansion/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "_from": "brace-expansion@^1.1.7", - "_id": "brace-expansion@1.1.11", - "_inBundle": false, - "_integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "_location": "/brace-expansion", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "brace-expansion@^1.1.7", - "name": "brace-expansion", - "escapedName": "brace-expansion", - "rawSpec": "^1.1.7", - "saveSpec": null, - "fetchSpec": "^1.1.7" - }, - "_requiredBy": [ - "/minimatch" - ], - "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "_shasum": "3c7fcbf529d87226f3d2f52b966ff5271eb441dd", - "_spec": "brace-expansion@^1.1.7", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\minimatch", - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "bugs": { - "url": "https://github.com/juliangruber/brace-expansion/issues" - }, - "bundleDependencies": false, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "deprecated": false, - "description": "Brace expansion as known from sh/bash", - "devDependencies": { - "matcha": "^0.7.0", - "tape": "^4.6.0" - }, - "homepage": "https://github.com/juliangruber/brace-expansion", - "keywords": [], - "license": "MIT", - "main": "index.js", - "name": "brace-expansion", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/brace-expansion.git" - }, - "scripts": { - "bench": "matcha test/perf/bench.js", - "gentest": "bash test/generate.sh", - "test": "tape test/*.js" - }, - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/8..latest", - "firefox/20..latest", - "firefox/nightly", - "chrome/25..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - }, - "version": "1.1.11" -} diff --git a/node_modules/concat-map/.travis.yml b/node_modules/concat-map/.travis.yml deleted file mode 100644 index f1d0f13c8..000000000 --- a/node_modules/concat-map/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - 0.4 - - 0.6 diff --git a/node_modules/concat-map/LICENSE b/node_modules/concat-map/LICENSE deleted file mode 100644 index ee27ba4b4..000000000 --- a/node_modules/concat-map/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -This software is released under the MIT license: - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/concat-map/README.markdown b/node_modules/concat-map/README.markdown deleted file mode 100644 index 408f70a1b..000000000 --- a/node_modules/concat-map/README.markdown +++ /dev/null @@ -1,62 +0,0 @@ -concat-map -========== - -Concatenative mapdashery. - -[![browser support](http://ci.testling.com/substack/node-concat-map.png)](http://ci.testling.com/substack/node-concat-map) - -[![build status](https://secure.travis-ci.org/substack/node-concat-map.png)](http://travis-ci.org/substack/node-concat-map) - -example -======= - -``` js -var concatMap = require('concat-map'); -var xs = [ 1, 2, 3, 4, 5, 6 ]; -var ys = concatMap(xs, function (x) { - return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; -}); -console.dir(ys); -``` - -*** - -``` -[ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ] -``` - -methods -======= - -``` js -var concatMap = require('concat-map') -``` - -concatMap(xs, fn) ------------------ - -Return an array of concatenated elements by calling `fn(x, i)` for each element -`x` and each index `i` in the array `xs`. - -When `fn(x, i)` returns an array, its result will be concatenated with the -result array. If `fn(x, i)` returns anything else, that value will be pushed -onto the end of the result array. - -install -======= - -With [npm](http://npmjs.org) do: - -``` -npm install concat-map -``` - -license -======= - -MIT - -notes -===== - -This module was written while sitting high above the ground in a tree. diff --git a/node_modules/concat-map/example/map.js b/node_modules/concat-map/example/map.js deleted file mode 100644 index 33656217b..000000000 --- a/node_modules/concat-map/example/map.js +++ /dev/null @@ -1,6 +0,0 @@ -var concatMap = require('../'); -var xs = [ 1, 2, 3, 4, 5, 6 ]; -var ys = concatMap(xs, function (x) { - return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; -}); -console.dir(ys); diff --git a/node_modules/concat-map/index.js b/node_modules/concat-map/index.js deleted file mode 100644 index b29a7812e..000000000 --- a/node_modules/concat-map/index.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x); - else res.push(x); - } - return res; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; diff --git a/node_modules/concat-map/package.json b/node_modules/concat-map/package.json deleted file mode 100644 index 383a72d8a..000000000 --- a/node_modules/concat-map/package.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "_from": "concat-map@0.0.1", - "_id": "concat-map@0.0.1", - "_inBundle": false, - "_integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "_location": "/concat-map", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "concat-map@0.0.1", - "name": "concat-map", - "escapedName": "concat-map", - "rawSpec": "0.0.1", - "saveSpec": null, - "fetchSpec": "0.0.1" - }, - "_requiredBy": [ - "/brace-expansion" - ], - "_resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", - "_spec": "concat-map@0.0.1", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\brace-expansion", - "author": { - "name": "James Halliday", - "email": "mail@substack.net", - "url": "http://substack.net" - }, - "bugs": { - "url": "https://github.com/substack/node-concat-map/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "concatenative mapdashery", - "devDependencies": { - "tape": "~2.4.0" - }, - "directories": { - "example": "example", - "test": "test" - }, - "homepage": "https://github.com/substack/node-concat-map#readme", - "keywords": [ - "concat", - "concatMap", - "map", - "functional", - "higher-order" - ], - "license": "MIT", - "main": "index.js", - "name": "concat-map", - "repository": { - "type": "git", - "url": "git://github.com/substack/node-concat-map.git" - }, - "scripts": { - "test": "tape test/*.js" - }, - "testling": { - "files": "test/*.js", - "browsers": { - "ie": [ - 6, - 7, - 8, - 9 - ], - "ff": [ - 3.5, - 10, - 15 - ], - "chrome": [ - 10, - 22 - ], - "safari": [ - 5.1 - ], - "opera": [ - 12 - ] - } - }, - "version": "0.0.1" -} diff --git a/node_modules/concat-map/test/map.js b/node_modules/concat-map/test/map.js deleted file mode 100644 index fdbd7022f..000000000 --- a/node_modules/concat-map/test/map.js +++ /dev/null @@ -1,39 +0,0 @@ -var concatMap = require('../'); -var test = require('tape'); - -test('empty or not', function (t) { - var xs = [ 1, 2, 3, 4, 5, 6 ]; - var ixes = []; - var ys = concatMap(xs, function (x, ix) { - ixes.push(ix); - return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; - }); - t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]); - t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]); - t.end(); -}); - -test('always something', function (t) { - var xs = [ 'a', 'b', 'c', 'd' ]; - var ys = concatMap(xs, function (x) { - return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ]; - }); - t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); - t.end(); -}); - -test('scalars', function (t) { - var xs = [ 'a', 'b', 'c', 'd' ]; - var ys = concatMap(xs, function (x) { - return x === 'b' ? [ 'B', 'B', 'B' ] : x; - }); - t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); - t.end(); -}); - -test('undefs', function (t) { - var xs = [ 'a', 'b', 'c', 'd' ]; - var ys = concatMap(xs, function () {}); - t.same(ys, [ undefined, undefined, undefined, undefined ]); - t.end(); -}); diff --git a/node_modules/fs.realpath/LICENSE b/node_modules/fs.realpath/LICENSE deleted file mode 100644 index 5bd884c25..000000000 --- a/node_modules/fs.realpath/LICENSE +++ /dev/null @@ -1,43 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ----- - -This library bundles a version of the `fs.realpath` and `fs.realpathSync` -methods from Node.js v0.10 under the terms of the Node.js MIT license. - -Node's license follows, also included at the header of `old.js` which contains -the licensed code: - - Copyright Joyent, Inc. and other Node contributors. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. diff --git a/node_modules/fs.realpath/README.md b/node_modules/fs.realpath/README.md deleted file mode 100644 index a42ceac62..000000000 --- a/node_modules/fs.realpath/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# fs.realpath - -A backwards-compatible fs.realpath for Node v6 and above - -In Node v6, the JavaScript implementation of fs.realpath was replaced -with a faster (but less resilient) native implementation. That raises -new and platform-specific errors and cannot handle long or excessively -symlink-looping paths. - -This module handles those cases by detecting the new errors and -falling back to the JavaScript implementation. On versions of Node -prior to v6, it has no effect. - -## USAGE - -```js -var rp = require('fs.realpath') - -// async version -rp.realpath(someLongAndLoopingPath, function (er, real) { - // the ELOOP was handled, but it was a bit slower -}) - -// sync version -var real = rp.realpathSync(someLongAndLoopingPath) - -// monkeypatch at your own risk! -// This replaces the fs.realpath/fs.realpathSync builtins -rp.monkeypatch() - -// un-do the monkeypatching -rp.unmonkeypatch() -``` diff --git a/node_modules/fs.realpath/index.js b/node_modules/fs.realpath/index.js deleted file mode 100644 index b09c7c7e6..000000000 --- a/node_modules/fs.realpath/index.js +++ /dev/null @@ -1,66 +0,0 @@ -module.exports = realpath -realpath.realpath = realpath -realpath.sync = realpathSync -realpath.realpathSync = realpathSync -realpath.monkeypatch = monkeypatch -realpath.unmonkeypatch = unmonkeypatch - -var fs = require('fs') -var origRealpath = fs.realpath -var origRealpathSync = fs.realpathSync - -var version = process.version -var ok = /^v[0-5]\./.test(version) -var old = require('./old.js') - -function newError (er) { - return er && er.syscall === 'realpath' && ( - er.code === 'ELOOP' || - er.code === 'ENOMEM' || - er.code === 'ENAMETOOLONG' - ) -} - -function realpath (p, cache, cb) { - if (ok) { - return origRealpath(p, cache, cb) - } - - if (typeof cache === 'function') { - cb = cache - cache = null - } - origRealpath(p, cache, function (er, result) { - if (newError(er)) { - old.realpath(p, cache, cb) - } else { - cb(er, result) - } - }) -} - -function realpathSync (p, cache) { - if (ok) { - return origRealpathSync(p, cache) - } - - try { - return origRealpathSync(p, cache) - } catch (er) { - if (newError(er)) { - return old.realpathSync(p, cache) - } else { - throw er - } - } -} - -function monkeypatch () { - fs.realpath = realpath - fs.realpathSync = realpathSync -} - -function unmonkeypatch () { - fs.realpath = origRealpath - fs.realpathSync = origRealpathSync -} diff --git a/node_modules/fs.realpath/old.js b/node_modules/fs.realpath/old.js deleted file mode 100644 index b40305e73..000000000 --- a/node_modules/fs.realpath/old.js +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var pathModule = require('path'); -var isWindows = process.platform === 'win32'; -var fs = require('fs'); - -// JavaScript implementation of realpath, ported from node pre-v6 - -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - var callback; - if (DEBUG) { - var backtrace = new Error; - callback = debugCallback; - } else - callback = missingCallback; - - return callback; - - function debugCallback(err) { - if (err) { - backtrace.message = err.message; - err = backtrace; - missingCallback(err); - } - } - - function missingCallback(err) { - if (err) { - if (process.throwDeprecation) - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - else if (!process.noDeprecation) { - var msg = 'fs: missing callback ' + (err.stack || err.message); - if (process.traceDeprecation) - console.trace(msg); - else - console.error(msg); - } - } - } -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -var normalize = pathModule.normalize; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -exports.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -exports.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; diff --git a/node_modules/fs.realpath/package.json b/node_modules/fs.realpath/package.json deleted file mode 100644 index 701a5805c..000000000 --- a/node_modules/fs.realpath/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "_from": "fs.realpath@^1.0.0", - "_id": "fs.realpath@1.0.0", - "_inBundle": false, - "_integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "_location": "/fs.realpath", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "fs.realpath@^1.0.0", - "name": "fs.realpath", - "escapedName": "fs.realpath", - "rawSpec": "^1.0.0", - "saveSpec": null, - "fetchSpec": "^1.0.0" - }, - "_requiredBy": [ - "/glob" - ], - "_resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "_shasum": "1504ad2523158caa40db4a2787cb01411994ea4f", - "_spec": "fs.realpath@^1.0.0", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "bugs": { - "url": "https://github.com/isaacs/fs.realpath/issues" - }, - "bundleDependencies": false, - "dependencies": {}, - "deprecated": false, - "description": "Use node's fs.realpath, but fall back to the JS implementation if the native one fails", - "devDependencies": {}, - "files": [ - "old.js", - "index.js" - ], - "homepage": "https://github.com/isaacs/fs.realpath#readme", - "keywords": [ - "realpath", - "fs", - "polyfill" - ], - "license": "ISC", - "main": "index.js", - "name": "fs.realpath", - "repository": { - "type": "git", - "url": "git+https://github.com/isaacs/fs.realpath.git" - }, - "scripts": { - "test": "tap test/*.js --cov" - }, - "version": "1.0.0" -} diff --git a/node_modules/glob-gitignore/HISTORY.md b/node_modules/glob-gitignore/HISTORY.md deleted file mode 100644 index e061a5372..000000000 --- a/node_modules/glob-gitignore/HISTORY.md +++ /dev/null @@ -1 +0,0 @@ -# History diff --git a/node_modules/glob-gitignore/LICENSE b/node_modules/glob-gitignore/LICENSE deleted file mode 100644 index a346b71e9..000000000 --- a/node_modules/glob-gitignore/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2013 kaelzhang , contributors -http://kael.me/ - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/glob-gitignore/README.md b/node_modules/glob-gitignore/README.md deleted file mode 100644 index 92147bc3d..000000000 --- a/node_modules/glob-gitignore/README.md +++ /dev/null @@ -1,121 +0,0 @@ -[![Build Status](https://travis-ci.org/kaelzhang/node-glob-gitignore.svg?branch=master)](https://travis-ci.org/kaelzhang/node-glob-gitignore) - - - - - -# glob-gitignore - -Extends [`glob`](https://www.npmjs.com/package/glob) with support for filtering files according to gitignore rules and exposes an optional Promise API, based on [`node-ignore`](https://www.npmjs.com/package/ignore). - -This module is built to solve performance issues, see [Why](#why). - -## Install - -```sh -$ npm i glob-gitignore --save -``` - -## Usage - -```js -import { - glob, - sync, - hasMagic -} from 'glob-gitignore' - -// The usage of glob-gitignore is much the same as `node-glob`, -// and it supports an array of patterns to be matched -glob(['**'], { - cwd: '/path/to', - - // Except that options.ignore accepts an array of gitignore rules, - // or a gitignore rule, - // or an `ignore` instance. - ignore: '*.bak' -}) -// And glob-gitignore returns a promise -.then(files => { - console.log(files) -}) - -// A string of pattern is also supported. -glob('**', options) - -// To glob things synchronously, use `sync` -const files = sync('**', {ignore: '*.bak'}) - -hasMagic('a/{b/c,x/y}') // true -``` - -## Why - -1. The `options.ignore` of `node-glob` does not support gitignore rules. - -2. It is better **NOT** to glob things then filter them by gitignore rules. Because by doing this, there will be so much unnecessary harddisk traversing, and cause performance issues, especially if there are tremendous files and directories inside the working directory. For the situation, you'd better to use this module. - -`glob-gitignore` does the filtering at the very process of each decending down. - -## glob(patterns, options) - -Returns a `Promise` - -- **patterns** `String|Array.` The pattern or array of patterns to be matched. - -And negative patterns (each of which starts with an `!`) are supported, although negative patterns are **NOT** recommended. You'd better to use `options.ignore`. - -```js -glob(['*.js', 'a/**', '!a/**/*.png']).then(console.log) -``` - -- **options** `Object` the [glob options](https://www.npmjs.com/package/glob#options) except for `options.ignore` - -### `options.ignore` - -Could be a `String`, an array of `String`s, or an instance of [node-`ignore`](https://www.npmjs.com/package/ignore) - -Not setting this is kind of silly, since that's the whole purpose of this lib, but it is optional though. - -```js -glob('**', {ignore: '*.js'}) -glob('**', {ignore: ['*.css', '*.styl']}) - -import ignore from 'ignore' -glob('**', { - ignore: ignore().add('*.js') -}) -``` - -## sync(patterns, options) - -The synchronous globber, which returns an `Array.`. - -## hasMagic(patterns, [options]) - -This method extends `glob.hasMagic(pattern)` and supports an array of patterns. - -Returns - -- `true` if there are any special characters in the pattern, or there is any of a pattern in the array has special characters. -- `false` otherwise. - -```js -hasMagic('a/{b/c,x/y}') // true -hasMagic(['a/{b/c,x/y}', 'a']) // true -hasMagic(['a']) // false -``` - -Note that the options affect the results. If `noext:true` is set in the options object, then `+(a|b)` will not be considered a magic pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}` then that is considered magical, unless `nobrace:true` is set in the options. - -## License - -MIT diff --git a/node_modules/glob-gitignore/package.json b/node_modules/glob-gitignore/package.json deleted file mode 100644 index 9aae07a88..000000000 --- a/node_modules/glob-gitignore/package.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "_from": "glob-gitignore", - "_id": "glob-gitignore@1.0.14", - "_inBundle": false, - "_integrity": "sha512-YuAEPqL58bOQDqDF2kMv009rIjSAtPs+WPzyGbwRWK+wD0UWQVRoP34Pz6yJ6ivco65C9tZnaIt0I3JCuQ8NZQ==", - "_location": "/glob-gitignore", - "_phantomChildren": {}, - "_requested": { - "type": "tag", - "registry": true, - "raw": "glob-gitignore", - "name": "glob-gitignore", - "escapedName": "glob-gitignore", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#USER", - "/" - ], - "_resolved": "https://registry.npmjs.org/glob-gitignore/-/glob-gitignore-1.0.14.tgz", - "_shasum": "8b708cb029e73bd388d22f7f935213aa93a1e7c2", - "_spec": "glob-gitignore", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge", - "author": { - "name": "kaelzhang" - }, - "ava": { - "babel": false - }, - "bugs": { - "url": "https://github.com/kaelzhang/node-glob-gitignore/issues" - }, - "bundleDependencies": false, - "dependencies": { - "glob": "^7.1.3", - "ignore": "^5.0.5", - "lodash.difference": "^4.5.0", - "lodash.union": "^4.6.0", - "make-array": "^1.0.5", - "util.inherits": "^1.0.3" - }, - "deprecated": false, - "description": "Extends `glob` with support for filtering files according to gitignore rules and exposes an optional Promise API with NO performance issues", - "devDependencies": { - "ava": "^1.2.1", - "codecov": "^3.2.0", - "eslint": "^5.14.1", - "eslint-config-ostai": "^1.4.0", - "eslint-plugin-import": "^2.16.0", - "nyc": "^13.3.0" - }, - "engines": { - "node": ">= 6" - }, - "files": [ - "src/" - ], - "homepage": "https://github.com/kaelzhang/node-glob-gitignore#readme", - "keywords": [ - "glob-gitignore", - "glob", - "gitignore", - "ignore", - "globby", - "promise", - "module", - "es-module" - ], - "license": "MIT", - "main": "src/index.js", - "name": "glob-gitignore", - "repository": { - "type": "git", - "url": "git://github.com/kaelzhang/node-glob-gitignore.git" - }, - "scripts": { - "lint": "eslint .", - "posttest": "nyc report --reporter=text-lcov > coverage.lcov && codecov", - "test": "nyc ava --timeout=10s", - "test-no-report": "NODE_DEBUG=ignore-nested nyc ava --timeout=10s --verbose" - }, - "version": "1.0.14" -} diff --git a/node_modules/glob-gitignore/src/glob.js b/node_modules/glob-gitignore/src/glob.js deleted file mode 100644 index 19b7d05a3..000000000 --- a/node_modules/glob-gitignore/src/glob.js +++ /dev/null @@ -1,68 +0,0 @@ -const {Glob} = require('glob') -const inherits = require('util.inherits') -const { - IGNORE, - createTasks -} = require('./util') -const {sync} = require('./sync') - -// Subclass of `glob.GlobSync` -// @param {string} pattern Pattern to be matched. -// @param {Object} options `options` for `glob` -// @param {function()} shouldIgnore Method to check whether a directory should be ignored. -// @constructor -function _Glob (pattern, options, callback, shouldIgnore) { - // We don't put this thing to argument `options` to avoid - // further problems, such as `options` validation. - - // Use `Symbol` as much as possible to avoid confliction. - this[IGNORE] = shouldIgnore - Glob.call(this, pattern, options, callback) -} - -inherits(_Glob, Glob) - -_Glob.prototype._readdir = function _readdir (abs, inGlobStar, cb) { - const marked = this._mark(abs) - - if (this[IGNORE] && this[IGNORE](marked)) { - return cb() - } - - return Glob.prototype._readdir.call(this, abs, inGlobStar, cb) -} - -function globOne (pattern, opts, ignore) { - return new Promise((resolve, reject) => { - new _Glob(pattern, opts, (err, files) => { - if (err) { - return reject(err) - } - - resolve(files) - }, ignore) - }) -} - -exports.glob = (_patterns, options = {}) => { - if (options.sync) { - return sync(_patterns, options) - } - - const { - patterns, - ignores, - join, - opts, - result - } = createTasks(_patterns, options) - - if (result) { - return Promise.resolve(result) - } - - return Promise.all( - patterns.map(pattern => globOne(pattern, opts, ignores)) - ) - .then(join) -} diff --git a/node_modules/glob-gitignore/src/index.js b/node_modules/glob-gitignore/src/index.js deleted file mode 100644 index b628ba5f7..000000000 --- a/node_modules/glob-gitignore/src/index.js +++ /dev/null @@ -1,15 +0,0 @@ -const make_array = require('make-array') -const vanilla = require('glob') - -const {sync} = require('./sync') -const {glob} = require('./glob') - -const hasMagic = (patterns, options) => - make_array(patterns) - .some(pattern => vanilla.hasMagic(pattern, options)) - -module.exports = { - sync, - glob, - hasMagic -} diff --git a/node_modules/glob-gitignore/src/sync.js b/node_modules/glob-gitignore/src/sync.js deleted file mode 100644 index f77cee37a..000000000 --- a/node_modules/glob-gitignore/src/sync.js +++ /dev/null @@ -1,50 +0,0 @@ -const {GlobSync} = require('glob') -const inherits = require('util.inherits') -const { - IGNORE, - createTasks -} = require('./util') - -function _GlobSync (pattern, options, shouldIgnore) { - this[IGNORE] = shouldIgnore - GlobSync.call(this, pattern, options) -} - -inherits(_GlobSync, GlobSync) - -_GlobSync.prototype._readdir = function _readdir (abs, inGlobStar) { - // `options.nodir` makes `options.mark` as `true`. - // Mark `abs` first - // to make sure `'node_modules'` will be ignored immediately - // with ignore pattern `'node_modules/'`. - - // There is a built-in cache about marked `File.Stat` in `glob`, - // so that we could not worry about the extra invocation of `this._mark()` - const marked = this._mark(abs) - - if (this[IGNORE] && this[IGNORE](marked)) { - return null - } - - return GlobSync.prototype._readdir.call(this, abs, inGlobStar) -} - -exports.sync = (_patterns, options = {}) => { - const { - join, - patterns, - ignores, - opts, - result - } = createTasks(_patterns, options) - - if (result) { - return result - } - - const groups = patterns.map( - pattern => new _GlobSync(pattern, opts, ignores).found - ) - - return join(groups) -} diff --git a/node_modules/glob-gitignore/src/util.js b/node_modules/glob-gitignore/src/util.js deleted file mode 100644 index a14e200ce..000000000 --- a/node_modules/glob-gitignore/src/util.js +++ /dev/null @@ -1,137 +0,0 @@ -const ignore = require('ignore') -const path = require('path') -const difference = require('lodash.difference') -const union = require('lodash.union') -const make_array = require('make-array') - -const IGNORE = typeof Symbol === 'function' - ? Symbol('ignore') - : '_shouldIgnore' - -const relative = (abs, cwd) => path.relative(cwd, abs) - -const createShouldIgnore = options => { - const opts = Object.assign({ - cache: Object.create(null), - statCache: Object.create(null), - realpathCache: Object.create(null), - symlinks: Object.create(null) - }, options) - - const { - ignore: ignores, - cwd = process.cwd() - } = opts - - delete opts.ignore - - if (!ignores) { - return { - ignore: () => false, - filter: () => true, - opts - } - } - - const ig = ignore().add(ignores) - const _filter = ig.createFilter() - - const filterABS = f => { - const filepath = relative(f, cwd) - if (!filepath) { - return true - } - - return _filter(filepath) - } - - const filter = options.absolute - ? filterABS - : _filter - - return { - // Check directories during traversing - ignores: f => !filterABS(f), - // Filter result - filter, - opts - } -} - -const isNegative = pattern => pattern[0] === '!' -const isPattern = subject => subject && typeof subject === 'string' - -const createTasks = (patterns, options) => { - patterns = make_array(patterns) - - if (!patterns.length || !patterns.every(isPattern)) { - throw new TypeError('patterns must be a string or an array of strings') - } - - const negativeFlags = [] - let positivesCount = 0 - patterns = patterns.map((pattern, i) => { - if (isNegative(pattern)) { - negativeFlags[i] = true - return pattern.slice(1) - } - - positivesCount ++ - return pattern - }) - - // or only provide a negative pattern - if (positivesCount === 0) { - return { - result: [] - } - } - - const { - opts, - filter, - ignores - } = createShouldIgnore(options) - - // Only one positive pattern - if (positivesCount === 1) { - return { - join ([files]) { - // _GlobSync only filters _readdir, - // so glob results should be filtered again. - return files.filter(filter) - }, - - patterns, - opts, - ignores - } - } - - return { - join (fileGroups) { - const positives = [] - const negatives = [] - - fileGroups.forEach((files, i) => { - /* eslint no-unused-expressions: 'off' */ - negativeFlags[i] - ? negatives.push(files) - : positives.push(files) - }) - - return difference(union(...positives), ...negatives) - // The same reason as above - .filter(filter) - }, - - patterns, - opts, - ignore - } -} - -module.exports = { - IGNORE, - createTasks -} diff --git a/node_modules/glob/LICENSE b/node_modules/glob/LICENSE deleted file mode 100644 index 42ca266df..000000000 --- a/node_modules/glob/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -## Glob Logo - -Glob's logo created by Tanya Brassie , licensed -under a Creative Commons Attribution-ShareAlike 4.0 International License -https://creativecommons.org/licenses/by-sa/4.0/ diff --git a/node_modules/glob/README.md b/node_modules/glob/README.md deleted file mode 100644 index 0916a4825..000000000 --- a/node_modules/glob/README.md +++ /dev/null @@ -1,375 +0,0 @@ -# Glob - -Match files using the patterns the shell uses, like stars and stuff. - -[![Build Status](https://travis-ci.org/isaacs/node-glob.svg?branch=master)](https://travis-ci.org/isaacs/node-glob/) [![Build Status](https://ci.appveyor.com/api/projects/status/kd7f3yftf7unxlsx?svg=true)](https://ci.appveyor.com/project/isaacs/node-glob) [![Coverage Status](https://coveralls.io/repos/isaacs/node-glob/badge.svg?branch=master&service=github)](https://coveralls.io/github/isaacs/node-glob?branch=master) - -This is a glob implementation in JavaScript. It uses the `minimatch` -library to do its matching. - -![](logo/glob.png) - -## Usage - -Install with npm - -``` -npm i glob -``` - -```javascript -var glob = require("glob") - -// options is optional -glob("**/*.js", options, function (er, files) { - // files is an array of filenames. - // If the `nonull` option is set, and nothing - // was found, then files is ["**/*.js"] - // er is an error object or null. -}) -``` - -## Glob Primer - -"Globs" are the patterns you type when you do stuff like `ls *.js` on -the command line, or put `build/*` in a `.gitignore` file. - -Before parsing the path part patterns, braced sections are expanded -into a set. Braced sections start with `{` and end with `}`, with any -number of comma-delimited sections within. Braced sections may contain -slash characters, so `a{/b/c,bcd}` would expand into `a/b/c` and `abcd`. - -The following characters have special magic meaning when used in a -path portion: - -* `*` Matches 0 or more characters in a single path portion -* `?` Matches 1 character -* `[...]` Matches a range of characters, similar to a RegExp range. - If the first character of the range is `!` or `^` then it matches - any character not in the range. -* `!(pattern|pattern|pattern)` Matches anything that does not match - any of the patterns provided. -* `?(pattern|pattern|pattern)` Matches zero or one occurrence of the - patterns provided. -* `+(pattern|pattern|pattern)` Matches one or more occurrences of the - patterns provided. -* `*(a|b|c)` Matches zero or more occurrences of the patterns provided -* `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns - provided -* `**` If a "globstar" is alone in a path portion, then it matches - zero or more directories and subdirectories searching for matches. - It does not crawl symlinked directories. - -### Dots - -If a file or directory path portion has a `.` as the first character, -then it will not match any glob pattern unless that pattern's -corresponding path part also has a `.` as its first character. - -For example, the pattern `a/.*/c` would match the file at `a/.b/c`. -However the pattern `a/*/c` would not, because `*` does not start with -a dot character. - -You can make glob treat dots as normal characters by setting -`dot:true` in the options. - -### Basename Matching - -If you set `matchBase:true` in the options, and the pattern has no -slashes in it, then it will seek for any file anywhere in the tree -with a matching basename. For example, `*.js` would match -`test/simple/basic.js`. - -### Empty Sets - -If no matching files are found, then an empty array is returned. This -differs from the shell, where the pattern itself is returned. For -example: - - $ echo a*s*d*f - a*s*d*f - -To get the bash-style behavior, set the `nonull:true` in the options. - -### See Also: - -* `man sh` -* `man bash` (Search for "Pattern Matching") -* `man 3 fnmatch` -* `man 5 gitignore` -* [minimatch documentation](https://github.com/isaacs/minimatch) - -## glob.hasMagic(pattern, [options]) - -Returns `true` if there are any special characters in the pattern, and -`false` otherwise. - -Note that the options affect the results. If `noext:true` is set in -the options object, then `+(a|b)` will not be considered a magic -pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}` -then that is considered magical, unless `nobrace:true` is set in the -options. - -## glob(pattern, [options], cb) - -* `pattern` `{String}` Pattern to be matched -* `options` `{Object}` -* `cb` `{Function}` - * `err` `{Error | null}` - * `matches` `{Array}` filenames found matching the pattern - -Perform an asynchronous glob search. - -## glob.sync(pattern, [options]) - -* `pattern` `{String}` Pattern to be matched -* `options` `{Object}` -* return: `{Array}` filenames found matching the pattern - -Perform a synchronous glob search. - -## Class: glob.Glob - -Create a Glob object by instantiating the `glob.Glob` class. - -```javascript -var Glob = require("glob").Glob -var mg = new Glob(pattern, options, cb) -``` - -It's an EventEmitter, and starts walking the filesystem to find matches -immediately. - -### new glob.Glob(pattern, [options], [cb]) - -* `pattern` `{String}` pattern to search for -* `options` `{Object}` -* `cb` `{Function}` Called when an error occurs, or matches are found - * `err` `{Error | null}` - * `matches` `{Array}` filenames found matching the pattern - -Note that if the `sync` flag is set in the options, then matches will -be immediately available on the `g.found` member. - -### Properties - -* `minimatch` The minimatch object that the glob uses. -* `options` The options object passed in. -* `aborted` Boolean which is set to true when calling `abort()`. There - is no way at this time to continue a glob search after aborting, but - you can re-use the statCache to avoid having to duplicate syscalls. -* `cache` Convenience object. Each field has the following possible - values: - * `false` - Path does not exist - * `true` - Path exists - * `'FILE'` - Path exists, and is not a directory - * `'DIR'` - Path exists, and is a directory - * `[file, entries, ...]` - Path exists, is a directory, and the - array value is the results of `fs.readdir` -* `statCache` Cache of `fs.stat` results, to prevent statting the same - path multiple times. -* `symlinks` A record of which paths are symbolic links, which is - relevant in resolving `**` patterns. -* `realpathCache` An optional object which is passed to `fs.realpath` - to minimize unnecessary syscalls. It is stored on the instantiated - Glob object, and may be re-used. - -### Events - -* `end` When the matching is finished, this is emitted with all the - matches found. If the `nonull` option is set, and no match was found, - then the `matches` list contains the original pattern. The matches - are sorted, unless the `nosort` flag is set. -* `match` Every time a match is found, this is emitted with the specific - thing that matched. It is not deduplicated or resolved to a realpath. -* `error` Emitted when an unexpected error is encountered, or whenever - any fs error occurs if `options.strict` is set. -* `abort` When `abort()` is called, this event is raised. - -### Methods - -* `pause` Temporarily stop the search -* `resume` Resume the search -* `abort` Stop the search forever - -### Options - -All the options that can be passed to Minimatch can also be passed to -Glob to change pattern matching behavior. Also, some have been added, -or have glob-specific ramifications. - -All options are false by default, unless otherwise noted. - -All options are added to the Glob object, as well. - -If you are running many `glob` operations, you can pass a Glob object -as the `options` argument to a subsequent operation to shortcut some -`stat` and `readdir` calls. At the very least, you may pass in shared -`symlinks`, `statCache`, `realpathCache`, and `cache` options, so that -parallel glob operations will be sped up by sharing information about -the filesystem. - -* `cwd` The current working directory in which to search. Defaults - to `process.cwd()`. -* `root` The place where patterns starting with `/` will be mounted - onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix - systems, and `C:\` or some such on Windows.) -* `dot` Include `.dot` files in normal matches and `globstar` matches. - Note that an explicit dot in a portion of the pattern will always - match dot files. -* `nomount` By default, a pattern starting with a forward-slash will be - "mounted" onto the root setting, so that a valid filesystem path is - returned. Set this flag to disable that behavior. -* `mark` Add a `/` character to directory matches. Note that this - requires additional stat calls. -* `nosort` Don't sort the results. -* `stat` Set to true to stat *all* results. This reduces performance - somewhat, and is completely unnecessary, unless `readdir` is presumed - to be an untrustworthy indicator of file existence. -* `silent` When an unusual error is encountered when attempting to - read a directory, a warning will be printed to stderr. Set the - `silent` option to true to suppress these warnings. -* `strict` When an unusual error is encountered when attempting to - read a directory, the process will just continue on in search of - other matches. Set the `strict` option to raise an error in these - cases. -* `cache` See `cache` property above. Pass in a previously generated - cache object to save some fs calls. -* `statCache` A cache of results of filesystem information, to prevent - unnecessary stat calls. While it should not normally be necessary - to set this, you may pass the statCache from one glob() call to the - options object of another, if you know that the filesystem will not - change between calls. (See "Race Conditions" below.) -* `symlinks` A cache of known symbolic links. You may pass in a - previously generated `symlinks` object to save `lstat` calls when - resolving `**` matches. -* `sync` DEPRECATED: use `glob.sync(pattern, opts)` instead. -* `nounique` In some cases, brace-expanded patterns can result in the - same file showing up multiple times in the result set. By default, - this implementation prevents duplicates in the result set. Set this - flag to disable that behavior. -* `nonull` Set to never return an empty set, instead returning a set - containing the pattern itself. This is the default in glob(3). -* `debug` Set to enable debug logging in minimatch and glob. -* `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets. -* `noglobstar` Do not match `**` against multiple filenames. (Ie, - treat it as a normal `*` instead.) -* `noext` Do not match `+(a|b)` "extglob" patterns. -* `nocase` Perform a case-insensitive match. Note: on - case-insensitive filesystems, non-magic patterns will match by - default, since `stat` and `readdir` will not raise errors. -* `matchBase` Perform a basename-only match if the pattern does not - contain any slash characters. That is, `*.js` would be treated as - equivalent to `**/*.js`, matching all js files in all directories. -* `nodir` Do not match directories, only files. (Note: to match - *only* directories, simply put a `/` at the end of the pattern.) -* `ignore` Add a pattern or an array of glob patterns to exclude matches. - Note: `ignore` patterns are *always* in `dot:true` mode, regardless - of any other settings. -* `follow` Follow symlinked directories when expanding `**` patterns. - Note that this can result in a lot of duplicate references in the - presence of cyclic links. -* `realpath` Set to true to call `fs.realpath` on all of the results. - In the case of a symlink that cannot be resolved, the full absolute - path to the matched entry is returned (though it will usually be a - broken symlink) -* `absolute` Set to true to always receive absolute paths for matched - files. Unlike `realpath`, this also affects the values returned in - the `match` event. - -## Comparisons to other fnmatch/glob implementations - -While strict compliance with the existing standards is a worthwhile -goal, some discrepancies exist between node-glob and other -implementations, and are intentional. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.3, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -Note that symlinked directories are not crawled as part of a `**`, -though their contents may match against subsequent portions of the -pattern. This prevents infinite loops and duplicates and the like. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then glob returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. - -### Comments and Negation - -Previously, this module let you mark a pattern as a "comment" if it -started with a `#` character, or a "negated" pattern if it started -with a `!` character. - -These options were deprecated in version 5, and removed in version 6. - -To specify things that should not match, use the `ignore` option. - -## Windows - -**Please only use forward-slashes in glob expressions.** - -Though windows uses either `/` or `\` as its path separator, only `/` -characters are used by this glob implementation. You must use -forward-slashes **only** in glob expressions. Back-slashes will always -be interpreted as escape characters, not path separators. - -Results from absolute patterns such as `/foo/*` are mounted onto the -root setting using `path.join`. On windows, this will by default result -in `/foo/*` matching `C:\foo\bar.txt`. - -## Race Conditions - -Glob searching, by its very nature, is susceptible to race conditions, -since it relies on directory walking and such. - -As a result, it is possible that a file that exists when glob looks for -it may have been deleted or modified by the time it returns the result. - -As part of its internal implementation, this program caches all stat -and readdir calls that it makes, in order to cut down on system -overhead. However, this also makes it even more susceptible to races, -especially if the cache or statCache objects are reused between glob -calls. - -Users are thus advised not to use a glob result as a guarantee of -filesystem state in the face of rapid changes. For the vast majority -of operations, this is never a problem. - -## Glob Logo -Glob's logo was created by [Tanya Brassie](http://tanyabrassie.com/). Logo files can be found [here](https://github.com/isaacs/node-glob/tree/master/logo). - -The logo is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/). - -## Contributing - -Any change to behavior (including bugfixes) must come with a test. - -Patches that fail tests or reduce performance will be rejected. - -``` -# to run tests -npm test - -# to re-generate test fixtures -npm run test-regen - -# to benchmark against bash/zsh -npm run bench - -# to profile javascript -npm run prof -``` - -![](oh-my-glob.gif) diff --git a/node_modules/glob/changelog.md b/node_modules/glob/changelog.md deleted file mode 100644 index 41636771e..000000000 --- a/node_modules/glob/changelog.md +++ /dev/null @@ -1,67 +0,0 @@ -## 7.0 - -- Raise error if `options.cwd` is specified, and not a directory - -## 6.0 - -- Remove comment and negation pattern support -- Ignore patterns are always in `dot:true` mode - -## 5.0 - -- Deprecate comment and negation patterns -- Fix regression in `mark` and `nodir` options from making all cache - keys absolute path. -- Abort if `fs.readdir` returns an error that's unexpected -- Don't emit `match` events for ignored items -- Treat ENOTSUP like ENOTDIR in readdir - -## 4.5 - -- Add `options.follow` to always follow directory symlinks in globstar -- Add `options.realpath` to call `fs.realpath` on all results -- Always cache based on absolute path - -## 4.4 - -- Add `options.ignore` -- Fix handling of broken symlinks - -## 4.3 - -- Bump minimatch to 2.x -- Pass all tests on Windows - -## 4.2 - -- Add `glob.hasMagic` function -- Add `options.nodir` flag - -## 4.1 - -- Refactor sync and async implementations for performance -- Throw if callback provided to sync glob function -- Treat symbolic links in globstar results the same as Bash 4.3 - -## 4.0 - -- Use `^` for dependency versions (bumped major because this breaks - older npm versions) -- Ensure callbacks are only ever called once -- switch to ISC license - -## 3.x - -- Rewrite in JavaScript -- Add support for setting root, cwd, and windows support -- Cache many fs calls -- Add globstar support -- emit match events - -## 2.x - -- Use `glob.h` and `fnmatch.h` from NetBSD - -## 1.x - -- `glob.h` static binding. diff --git a/node_modules/glob/common.js b/node_modules/glob/common.js deleted file mode 100644 index 66651bb3a..000000000 --- a/node_modules/glob/common.js +++ /dev/null @@ -1,240 +0,0 @@ -exports.alphasort = alphasort -exports.alphasorti = alphasorti -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored - -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var path = require("path") -var minimatch = require("minimatch") -var isAbsolute = require("path-is-absolute") -var Minimatch = minimatch.Minimatch - -function alphasorti (a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()) -} - -function alphasort (a, b) { - return a.localeCompare(b) -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} - -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { dot: true }) - } - - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher - } -} - -function setopts (self, pattern, options) { - if (!options) - options = {} - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - self.absolute = !!options.absolute - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) - - setupIgnores(self, options) - - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = cwd - else { - self.cwd = path.resolve(options.cwd) - self.changedCwd = self.cwd !== cwd - } - - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") - - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") - self.nomount = !!options.nomount - - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true - options.nocomment = true - - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options -} - -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(self.nocase ? alphasorti : alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)) - var c = self.cache[e] || self.cache[makeAbs(self, e)] - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c) - return notDir - }) - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) - - self.found = all -} - -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) - } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/') - - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} diff --git a/node_modules/glob/glob.js b/node_modules/glob/glob.js deleted file mode 100644 index 58dec0f6c..000000000 --- a/node_modules/glob/glob.js +++ /dev/null @@ -1,790 +0,0 @@ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -module.exports = glob - -var fs = require('fs') -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var inherits = require('inherits') -var EE = require('events').EventEmitter -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var globSync = require('./sync.js') -var common = require('./common.js') -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = require('inflight') -var util = require('util') -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -var once = require('once') - -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} - - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } - - return new Glob(pattern, options, cb) -} - -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync - -// old api surface -glob.glob = glob - -function extend (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } - - var keys = Object.keys(add) - var i = keys.length - while (i--) { - origin[keys[i]] = add[keys[i]] - } - return origin -} - -glob.hasMagic = function (pattern, options_) { - var options = extend({}, options_) - options.noprocess = true - - var g = new Glob(pattern, options) - var set = g.minimatch.set - - if (!pattern) - return false - - if (set.length > 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -} - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options) - this._didRealPath = false - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) - } - - var self = this - this._processing = 0 - - this._emitQueue = [] - this._processQueue = [] - this.paused = false - - if (this.noprocess) - return this - - if (n === 0) - return done() - - var sync = true - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - sync = false - - function done () { - --self._processing - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish() - }) - } else { - self._finish() - } - } - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this) - this.emit('end', this.found) -} - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true - - var n = this.matches.length - if (n === 0) - return this._finish() - - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) - - function next () { - if (--n === 0) - self._finish() - } -} - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() - - var found = Object.keys(matchset) - var self = this - var n = found.length - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) -} - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } - } -} - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') - - if (this.aborted) - return - - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) -} - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() -} - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } - - var abs = isAbsolute(e) ? e : this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) - e = abs - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) - - this.emit('match', e) -} - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) - - if (lstatcb) - fs.lstat(abs, lstatcb) - - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() - - var isSym = lstat && lstat.isSymbolicLink() - self.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } -} - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - - var self = this - fs.readdir(abs, readdirCb(this, abs, cb)) -} - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - return cb(null, entries) -} - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - this.emit('error', error) - this.abort() - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break - } - - return cb() -} - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) - - var isSym = this.symlinks[abs] - var len = entries.length - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) - } - - cb() -} - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) -} -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - fs.lstat(abs, statcb) - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) - } - } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return cb() - } - - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return cb() - - return cb(null, c, stat) -} diff --git a/node_modules/glob/package.json b/node_modules/glob/package.json deleted file mode 100644 index 42043282c..000000000 --- a/node_modules/glob/package.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "_from": "glob", - "_id": "glob@7.1.6", - "_inBundle": false, - "_integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "_location": "/glob", - "_phantomChildren": {}, - "_requested": { - "type": "tag", - "registry": true, - "raw": "glob", - "name": "glob", - "escapedName": "glob", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#USER", - "/" - ], - "_resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "_shasum": "141f33b81a7c2492e125594307480c46679278a6", - "_spec": "glob", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "bugs": { - "url": "https://github.com/isaacs/node-glob/issues" - }, - "bundleDependencies": false, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "deprecated": false, - "description": "a little globber", - "devDependencies": { - "mkdirp": "0", - "rimraf": "^2.2.8", - "tap": "^12.0.1", - "tick": "0.0.6" - }, - "engines": { - "node": "*" - }, - "files": [ - "glob.js", - "sync.js", - "common.js" - ], - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "homepage": "https://github.com/isaacs/node-glob#readme", - "license": "ISC", - "main": "glob.js", - "name": "glob", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-glob.git" - }, - "scripts": { - "bench": "bash benchmark.sh", - "benchclean": "node benchclean.js", - "prepublish": "npm run benchclean", - "prof": "bash prof.sh && cat profile.txt", - "profclean": "rm -f v8.log profile.txt", - "test": "tap test/*.js --cov", - "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js" - }, - "version": "7.1.6" -} diff --git a/node_modules/glob/sync.js b/node_modules/glob/sync.js deleted file mode 100644 index c952134ba..000000000 --- a/node_modules/glob/sync.js +++ /dev/null @@ -1,486 +0,0 @@ -module.exports = globSync -globSync.GlobSync = GlobSync - -var fs = require('fs') -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var Glob = require('./glob.js').Glob -var util = require('util') -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var common = require('./common.js') -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync(pattern, options).found -} - -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) - - setopts(this, pattern, options) - - if (this.noprocess) - return this - - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) - } - this._finish() -} - -GlobSync.prototype._finish = function () { - assert(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = rp.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } - } - }) - } - common.finish(this) -} - - -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert(this instanceof GlobSync) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip processing - if (childrenIgnored(this, read)) - return - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} - - -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} - - -GlobSync.prototype._emitMatch = function (index, e) { - if (isIgnored(this, e)) - return - - var abs = this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) { - e = abs - } - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - if (this.stat) - this._stat(e) -} - - -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries - var lstat - var stat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null - } - } - - var isSym = lstat && lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) - - return entries -} - -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries - - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} - -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - - // mark and cache dir-ness - return entries -} - -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - throw error - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} - -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) - - var len = entries.length - var isSym = this.symlinks[abs] - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} - -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) -} - -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return false - } - } - - if (lstat && lstat.isSymbolicLink()) { - try { - stat = fs.statSync(abs) - } catch (er) { - stat = lstat - } - } else { - stat = lstat - } - } - - this.statCache[abs] = stat - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return false - - return c -} - -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} - -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} diff --git a/node_modules/ignore/CHANGELOG.md b/node_modules/ignore/CHANGELOG.md deleted file mode 100644 index dc38d633a..000000000 --- a/node_modules/ignore/CHANGELOG.md +++ /dev/null @@ -1,32 +0,0 @@ -# `node-ignore` 5 ChangeLog - -# 5.x - -## 2018-08-14, Version 5.0.1 - -- **PATCH**: fixes for windows. -- **PATCH**: improves tests for typescript and windows. - -## 2018-08-13, Version 5.0.0 - -- **SEMVER-MAJOR**: [#20](https://github.com/kaelzhang/node-ignore/issues/20): it will throw if an invalid pathname passes into `.ignores(pathname)`, see [Upgrade 4.x -> 5.x](https://github.com/kaelzhang/node-ignore#upgrade-4x---5x). -- **FEATURE**: [#31](https://github.com/kaelzhang/node-ignore/issues/31): adds a new method [`.test(pathname)`](https://github.com/kaelzhang/node-ignore#testpathname-pathname-since-500). -- **BENCHMARK**: improves performance by 26%. - -# 4.x - -## 2018-08-12, Version 4.0.6 - -- **PATCH**: `Object.prototype` methods will not ruin the result any more. - -## ~ 2018-08-09, Version 4.0.1 - 4.0.5 - -- **PATCH**: updates README.md about frequent asked quesions from github issues. - -## 2018-06-22, Version 4.0.0 - -- **SEMVER-MAJOR**: Drop support for node < 6 by default. -- **FEATURE**: supports the missing character ranges and sets, such as `*.[a-z]` and `*.[jJ][pP][gG]` -- **FEATURE**: new option: `ignorecase` to make `ignore` case insensitive. -- **FEATURE**: supports question mark which matches a single character. -- **PATCH**: fixes typescript declaration. diff --git a/node_modules/ignore/LICENSE-MIT b/node_modules/ignore/LICENSE-MIT deleted file mode 100644 index 825533e33..000000000 --- a/node_modules/ignore/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2013 Kael Zhang , contributors -http://kael.me/ - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/ignore/README.md b/node_modules/ignore/README.md deleted file mode 100644 index c52b32519..000000000 --- a/node_modules/ignore/README.md +++ /dev/null @@ -1,386 +0,0 @@ - - - - - - - - - - - - - -
LinuxOS XWindowsCoverageDownloads
- - Build Status - - - Windows Build Status - - - Coverage Status - - - npm module downloads per month -
- -# ignore - -`ignore` is a manager, filter and parser which implemented in pure JavaScript according to the .gitignore [spec](http://git-scm.com/docs/gitignore). - -`ignore` is used by eslint, gitbook and [many others](https://www.npmjs.com/browse/depended/ignore). - -Pay attention that [`minimatch`](https://www.npmjs.org/package/minimatch) does not work in the gitignore way. To filter filenames according to .gitignore file, I recommend this module. - -### Tested on - -`ignore` is fully tested, and has more than **five hundreds** of unit tests. - -- Linux + Node: `0.8` - `7.x` -- Windows + Node: `0.10` - `7.x`, node < `0.10` is not tested due to the lack of support of appveyor. - -Actually, `ignore` does not rely on any versions of node specially. - -Since `4.0.0`, ignore will no longer support `node < 6` by default, to use in node < 6, `require('ignore/legacy')`. For details, see [CHANGELOG](https://github.com/kaelzhang/node-ignore/blob/master/CHANGELOG.md). - -## Table Of Main Contents - -- [Usage](#usage) -- [`Pathname` Conventions](#pathname-conventions) -- See Also: - - [`glob-gitignore`](https://www.npmjs.com/package/glob-gitignore) matches files using patterns and filters them according to gitignore rules. -- [Upgrade Guide](#upgrade-guide) - -## Install - -```sh -npm i ignore -``` - -## Usage - -```js -import ignore from 'ignore' -const ig = ignore().add(['.abc/*', '!.abc/d/']) -``` - -### Filter the given paths - -```js -const paths = [ - '.abc/a.js', // filtered out - '.abc/d/e.js' // included -] - -ig.filter(paths) // ['.abc/d/e.js'] -ig.ignores('.abc/a.js') // true -``` - -### As the filter function - -```js -paths.filter(ig.createFilter()); // ['.abc/d/e.js'] -``` - -### Win32 paths will be handled - -```js -ig.filter(['.abc\\a.js', '.abc\\d\\e.js']) -// if the code above runs on windows, the result will be -// ['.abc\\d\\e.js'] -``` - -## Why another ignore? - -- `ignore` is a standalone module, and is much simpler so that it could easy work with other programs, unlike [isaacs](https://npmjs.org/~isaacs)'s [fstream-ignore](https://npmjs.org/package/fstream-ignore) which must work with the modules of the fstream family. - -- `ignore` only contains utility methods to filter paths according to the specified ignore rules, so - - `ignore` never try to find out ignore rules by traversing directories or fetching from git configurations. - - `ignore` don't cares about sub-modules of git projects. - -- Exactly according to [gitignore man page](http://git-scm.com/docs/gitignore), fixes some known matching issues of fstream-ignore, such as: - - '`/*.js`' should only match '`a.js`', but not '`abc/a.js`'. - - '`**/foo`' should match '`foo`' anywhere. - - Prevent re-including a file if a parent directory of that file is excluded. - - Handle trailing whitespaces: - - `'a '`(one space) should not match `'a '`(two spaces). - - `'a \ '` matches `'a '` - - All test cases are verified with the result of `git check-ignore`. - -# Methods - -## .add(pattern: string | Ignore): this -## .add(patterns: Array): this - -- **pattern** `String | Ignore` An ignore pattern string, or the `Ignore` instance -- **patterns** `Array` Array of ignore patterns. - -Adds a rule or several rules to the current manager. - -Returns `this` - -Notice that a line starting with `'#'`(hash) is treated as a comment. Put a backslash (`'\'`) in front of the first hash for patterns that begin with a hash, if you want to ignore a file with a hash at the beginning of the filename. - -```js -ignore().add('#abc').ignores('#abc') // false -ignore().add('\#abc').ignores('#abc') // true -``` - -`pattern` could either be a line of ignore pattern or a string of multiple ignore patterns, which means we could just `ignore().add()` the content of a ignore file: - -```js -ignore() -.add(fs.readFileSync(filenameOfGitignore).toString()) -.filter(filenames) -``` - -`pattern` could also be an `ignore` instance, so that we could easily inherit the rules of another `Ignore` instance. - -## .addIgnoreFile(path) - -REMOVED in `3.x` for now. - -To upgrade `ignore@2.x` up to `3.x`, use - -```js -import fs from 'fs' - -if (fs.existsSync(filename)) { - ignore().add(fs.readFileSync(filename).toString()) -} -``` - -instead. - -## .filter(paths: Array<Pathname>): Array<Pathname> - -```ts -type Pathname = string -``` - -Filters the given array of pathnames, and returns the filtered array. - -- **paths** `Array.` The array of `pathname`s to be filtered. - -### `Pathname` Conventions: - -#### 1. `Pathname` should be a `path.relative()`d pathname - -`Pathname` should be a string that have been `path.join()`ed, or the return value of `path.relative()` to the current directory, - -```js -// WRONG, an error will be thrown -ig.ignores('./abc') - -// WRONG, for it will never happen, and an error will be thrown -// If the gitignore rule locates at the root directory, -// `'/abc'` should be changed to `'abc'`. -// ``` -// path.relative('/', '/abc') -> 'abc' -// ``` -ig.ignores('/abc') - -// WRONG, that it is an absolute path on Windows, an error will be thrown -ig.ignores('C:\\abc') - -// Right -ig.ignores('abc') - -// Right -ig.ignores(path.join('./abc')) // path.join('./abc') -> 'abc' -``` - -In other words, each `Pathname` here should be a relative path to the directory of the gitignore rules. - -Suppose the dir structure is: - -``` -/path/to/your/repo - |-- a - | |-- a.js - | - |-- .b - | - |-- .c - |-- .DS_store -``` - -Then the `paths` might be like this: - -```js -[ - 'a/a.js' - '.b', - '.c/.DS_store' -] -``` - -#### 2. filenames and dirnames - -`node-ignore` does NO `fs.stat` during path matching, so for the example below: - -```js -// First, we add a ignore pattern to ignore a directory -ig.add('config/') - -// `ig` does NOT know if 'config', in the real world, -// is a normal file, directory or something. - -ig.ignores('config') -// `ig` treats `config` as a file, so it returns `false` - -ig.ignores('config/') -// returns `true` -``` - -Specially for people who develop some library based on `node-ignore`, it is important to understand that. - -Usually, you could use [`glob`](http://npmjs.org/package/glob) with `option.mark = true` to fetch the structure of the current directory: - -```js -import glob from 'glob' - -glob('**', { - // Adds a / character to directory matches. - mark: true -}, (err, files) => { - if (err) { - return console.error(err) - } - - let filtered = ignore().add(patterns).filter(files) - console.log(filtered) -}) -``` - -## .ignores(pathname: Pathname): boolean - -> new in 3.2.0 - -Returns `Boolean` whether `pathname` should be ignored. - -```js -ig.ignores('.abc/a.js') // true -``` - -## .createFilter() - -Creates a filter function which could filter an array of paths with `Array.prototype.filter`. - -Returns `function(path)` the filter function. - -## .test(pathname: Pathname) since 5.0.0 - -Returns `TestResult` - -```ts -interface TestResult { - ignored: boolean - // true if the `pathname` is finally unignored by some negative pattern - unignored: boolean -} -``` - -- `{ignored: true, unignored: false}`: the `pathname` is ignored -- `{ignored: false, unignored: true}`: the `pathname` is unignored -- `{ignored: false, unignored: false}`: the `pathname` is never matched by any ignore rules. - -## `options.ignorecase` since 4.0.0 - -Similar as the `core.ignorecase` option of [git-config](https://git-scm.com/docs/git-config), `node-ignore` will be case insensitive if `options.ignorecase` is set to `true` (the default value), otherwise case sensitive. - -```js -const ig = ignore({ - ignorecase: false -}) - -ig.add('*.png') - -ig.ignores('*.PNG') // false -``` - -## static `ignore.isPathValid(pathname): boolean` since 5.0.0 - -Check whether the `pathname` is valid according to the [convention](#1-pathname-should-be-a-pathrelatived-pathname). - -```js -ignore.isPathValid('./foo') // false -``` - -**** - -# Upgrade Guide - -## Upgrade 4.x -> 5.x - -Since `5.0.0`, if an invalid `Pathname` passed into `ig.ignores()`, an error will be thrown, while `ignore < 5.0.0` did not make sure what the return value was, as well as - -```ts -.ignores(pathname: Pathname): boolean - -.filter(pathnames: Array): Array - -.createFilter(): (pathname: Pathname) => boolean - -.test(pathname: Pathname): {ignored: boolean, unignored: boolean} -``` - -See the convention [here](#1-pathname-should-be-a-pathrelatived-pathname) for details. - -If there are invalid pathnames, the conversion and filtration should be done by users. - -```js -import {isPathValid} from 'ignore' // introduced in 5.0.0 - -const paths = [ - // invalid - ////////////////// - '', - false, - '../foo', - '.', - ////////////////// - - // valid - 'foo' -] -.filter(isValidPath) - -ig.filter(paths) -``` - -## Upgrade 3.x -> 4.x - -Since `4.0.0`, `ignore` will no longer support node < 6, to use `ignore` in node < 6: - -```js -var ignore = require('ignore/legacy') -``` - -## Upgrade 2.x -> 3.x - -- All `options` of 2.x are unnecessary and removed, so just remove them. -- `ignore()` instance is no longer an [`EventEmitter`](nodejs.org/api/events.html), and all events are unnecessary and removed. -- `.addIgnoreFile()` is removed, see the [.addIgnoreFile](#addignorefilepath) section for details. - -**** - -# Collaborators - -- [@whitecolor](https://github.com/whitecolor) *Alex* -- [@SamyPesse](https://github.com/SamyPesse) *Samy Pessé* -- [@azproduction](https://github.com/azproduction) *Mikhail Davydov* -- [@TrySound](https://github.com/TrySound) *Bogdan Chadkin* -- [@JanMattner](https://github.com/JanMattner) *Jan Mattner* -- [@ntwb](https://github.com/ntwb) *Stephen Edgar* -- [@kasperisager](https://github.com/kasperisager) *Kasper Isager* -- [@sandersn](https://github.com/sandersn) *Nathan Shively-Sanders* diff --git a/node_modules/ignore/index.d.ts b/node_modules/ignore/index.d.ts deleted file mode 100644 index 66657af5e..000000000 --- a/node_modules/ignore/index.d.ts +++ /dev/null @@ -1,63 +0,0 @@ -type Pathname = string - -interface TestResult { - ignored: boolean - unignored: boolean -} - -export interface Ignore { - /** - * Adds a rule rules to the current manager. - * @param {string | Ignore} pattern - * @returns IgnoreBase - */ - add(pattern: string | Ignore): this - /** - * Adds several rules to the current manager. - * @param {string[]} patterns - * @returns IgnoreBase - */ - add(patterns: (string | Ignore)[]): this - - /** - * Filters the given array of pathnames, and returns the filtered array. - * NOTICE that each path here should be a relative path to the root of your repository. - * @param paths the array of paths to be filtered. - * @returns The filtered array of paths - */ - filter(pathnames: Pathname[]): Pathname[] - /** - * Creates a filter function which could filter - * an array of paths with Array.prototype.filter. - */ - createFilter(): (pathname: Pathname) => boolean - - /** - * Returns Boolean whether pathname should be ignored. - * @param {string} pathname a path to check - * @returns boolean - */ - ignores(pathname: Pathname): boolean - - /** - * Returns whether pathname should be ignored or unignored - * @param {string} pathname a path to check - * @returns TestResult - */ - test(pathname: Pathname): TestResult -} - -interface Options { - ignorecase?: boolean -} - -/** - * Creates new ignore manager. - */ -declare function ignore(options?: Options): Ignore - -declare namespace ignore { - export function isPathValid (pathname: string): boolean -} - -export default ignore diff --git a/node_modules/ignore/index.js b/node_modules/ignore/index.js deleted file mode 100644 index 8ee485873..000000000 --- a/node_modules/ignore/index.js +++ /dev/null @@ -1,568 +0,0 @@ -// A simple implementation of make-array -function makeArray (subject) { - return Array.isArray(subject) - ? subject - : [subject] -} - -const REGEX_TEST_BLANK_LINE = /^\s+$/ -const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/ -const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/ -const REGEX_SPLITALL_CRLF = /\r?\n/g -// /foo, -// ./foo, -// ../foo, -// . -// .. -const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/ - -const SLASH = '/' -const KEY_IGNORE = typeof Symbol !== 'undefined' - ? Symbol.for('node-ignore') - /* istanbul ignore next */ - : 'node-ignore' - -const define = (object, key, value) => - Object.defineProperty(object, key, {value}) - -const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g - -// Sanitize the range of a regular expression -// The cases are complicated, see test cases for details -const sanitizeRange = range => range.replace( - REGEX_REGEXP_RANGE, - (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) - ? match - // Invalid range (out of order) which is ok for gitignore rules but - // fatal for JavaScript regular expression, so eliminate it. - : '' -) - -// > If the pattern ends with a slash, -// > it is removed for the purpose of the following description, -// > but it would only find a match with a directory. -// > In other words, foo/ will match a directory foo and paths underneath it, -// > but will not match a regular file or a symbolic link foo -// > (this is consistent with the way how pathspec works in general in Git). -// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' -// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call -// you could use option `mark: true` with `glob` - -// '`foo/`' should not continue with the '`..`' -const REPLACERS = [ - - // > Trailing spaces are ignored unless they are quoted with backslash ("\") - [ - // (a\ ) -> (a ) - // (a ) -> (a) - // (a \ ) -> (a ) - /\\?\s+$/, - match => match.indexOf('\\') === 0 - ? ' ' - : '' - ], - - // replace (\ ) with ' ' - [ - /\\\s/g, - () => ' ' - ], - - // Escape metacharacters - // which is written down by users but means special for regular expressions. - - // > There are 12 characters with special meanings: - // > - the backslash \, - // > - the caret ^, - // > - the dollar sign $, - // > - the period or dot ., - // > - the vertical bar or pipe symbol |, - // > - the question mark ?, - // > - the asterisk or star *, - // > - the plus sign +, - // > - the opening parenthesis (, - // > - the closing parenthesis ), - // > - and the opening square bracket [, - // > - the opening curly brace {, - // > These special characters are often called "metacharacters". - [ - /[\\^$.|*+(){]/g, - match => `\\${match}` - ], - - [ - // > [abc] matches any character inside the brackets - // > (in this case a, b, or c); - /\[([^\]/]*)($|\])/g, - (match, p1, p2) => p2 === ']' - ? `[${sanitizeRange(p1)}]` - : `\\${match}` - ], - - [ - // > a question mark (?) matches a single character - /(?!\\)\?/g, - () => '[^/]' - ], - - // leading slash - [ - - // > A leading slash matches the beginning of the pathname. - // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". - // A leading slash matches the beginning of the pathname - /^\//, - () => '^' - ], - - // replace special metacharacter slash after the leading slash - [ - /\//g, - () => '\\/' - ], - - [ - // > A leading "**" followed by a slash means match in all directories. - // > For example, "**/foo" matches file or directory "foo" anywhere, - // > the same as pattern "foo". - // > "**/foo/bar" matches file or directory "bar" anywhere that is directly - // > under directory "foo". - // Notice that the '*'s have been replaced as '\\*' - /^\^*\\\*\\\*\\\//, - - // '**/foo' <-> 'foo' - () => '^(?:.*\\/)?' - ], - - // ending - [ - // 'js' will not match 'js.' - // 'ab' will not match 'abc' - /(?:[^*])$/, - - // WTF! - // https://git-scm.com/docs/gitignore - // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) - // which re-fixes #24, #38 - - // > If there is a separator at the end of the pattern then the pattern - // > will only match directories, otherwise the pattern can match both - // > files and directories. - - // 'js*' will not match 'a.js' - // 'js/' will not match 'a.js' - // 'js' will match 'a.js' and 'a.js/' - match => /\/$/.test(match) - // foo/ will not match 'foo' - ? `${match}$` - // foo matches 'foo' and 'foo/' - : `${match}(?=$|\\/$)` - ], - - // starting - [ - // there will be no leading '/' - // (which has been replaced by section "leading slash") - // If starts with '**', adding a '^' to the regular expression also works - /^(?=[^^])/, - function startingReplacer () { - // If has a slash `/` at the beginning or middle - return !/\/(?!$)/.test(this) - // > Prior to 2.22.1 - // > If the pattern does not contain a slash /, - // > Git treats it as a shell glob pattern - // Actually, if there is only a trailing slash, - // git also treats it as a shell glob pattern - - // After 2.22.1 (compatible but clearer) - // > If there is a separator at the beginning or middle (or both) - // > of the pattern, then the pattern is relative to the directory - // > level of the particular .gitignore file itself. - // > Otherwise the pattern may also match at any level below - // > the .gitignore level. - ? '(?:^|\\/)' - - // > Otherwise, Git treats the pattern as a shell glob suitable for - // > consumption by fnmatch(3) - : '^' - } - ], - - // two globstars - [ - // Use lookahead assertions so that we could match more than one `'/**'` - /\\\/\\\*\\\*(?=\\\/|$)/g, - - // Zero, one or several directories - // should not use '*', or it will be replaced by the next replacer - - // Check if it is not the last `'/**'` - (_, index, str) => index + 6 < str.length - - // case: /**/ - // > A slash followed by two consecutive asterisks then a slash matches - // > zero or more directories. - // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. - // '/**/' - ? '(?:\\/[^\\/]+)*' - - // case: /** - // > A trailing `"/**"` matches everything inside. - - // #21: everything inside but it should not include the current folder - : '\\/.+' - ], - - // intermediate wildcards - [ - // Never replace escaped '*' - // ignore rule '\*' will match the path '*' - - // 'abc.*/' -> go - // 'abc.*' -> skip this rule - /(^|[^\\]+)\\\*(?=.+)/g, - - // '*.js' matches '.js' - // '*.js' doesn't match 'abc' - (_, p1) => `${p1}[^\\/]*` - ], - - // trailing wildcard - [ - /(\^|\\\/)?\\\*$/, - (_, p1) => { - const prefix = p1 - // '\^': - // '/*' does not match '' - // '/*' does not match everything - - // '\\\/': - // 'abc/*' does not match 'abc/' - ? `${p1}[^/]+` - - // 'a*' matches 'a' - // 'a*' matches 'aa' - : '[^/]*' - - return `${prefix}(?=$|\\/$)` - } - ], - - [ - // unescape - /\\\\\\/g, - () => '\\' - ] -] - -// A simple cache, because an ignore rule only has only one certain meaning -const regexCache = Object.create(null) - -// @param {pattern} -const makeRegex = (pattern, negative, ignorecase) => { - const r = regexCache[pattern] - if (r) { - return r - } - - // const replacers = negative - // ? NEGATIVE_REPLACERS - // : POSITIVE_REPLACERS - - const source = REPLACERS.reduce( - (prev, current) => prev.replace(current[0], current[1].bind(pattern)), - pattern - ) - - return regexCache[pattern] = ignorecase - ? new RegExp(source, 'i') - : new RegExp(source) -} - -const isString = subject => typeof subject === 'string' - -// > A blank line matches no files, so it can serve as a separator for readability. -const checkPattern = pattern => pattern - && isString(pattern) - && !REGEX_TEST_BLANK_LINE.test(pattern) - - // > A line starting with # serves as a comment. - && pattern.indexOf('#') !== 0 - -const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF) - -class IgnoreRule { - constructor ( - origin, - pattern, - negative, - regex - ) { - this.origin = origin - this.pattern = pattern - this.negative = negative - this.regex = regex - } -} - -const createRule = (pattern, ignorecase) => { - const origin = pattern - let negative = false - - // > An optional prefix "!" which negates the pattern; - if (pattern.indexOf('!') === 0) { - negative = true - pattern = pattern.substr(1) - } - - pattern = pattern - // > Put a backslash ("\") in front of the first "!" for patterns that - // > begin with a literal "!", for example, `"\!important!.txt"`. - .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') - // > Put a backslash ("\") in front of the first hash for patterns that - // > begin with a hash. - .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#') - - const regex = makeRegex(pattern, negative, ignorecase) - - return new IgnoreRule( - origin, - pattern, - negative, - regex - ) -} - -const throwError = (message, Ctor) => { - throw new Ctor(message) -} - -const checkPath = (path, originalPath, doThrow) => { - if (!isString(path)) { - return doThrow( - `path must be a string, but got \`${originalPath}\``, - TypeError - ) - } - - // We don't know if we should ignore '', so throw - if (!path) { - return doThrow(`path must not be empty`, TypeError) - } - - // Check if it is a relative path - if (checkPath.isNotRelative(path)) { - const r = '`path.relative()`d' - return doThrow( - `path should be a ${r} string, but got "${originalPath}"`, - RangeError - ) - } - - return true -} - -const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path) - -checkPath.isNotRelative = isNotRelative -checkPath.convert = p => p - -class Ignore { - constructor ({ - ignorecase = true - } = {}) { - this._rules = [] - this._ignorecase = ignorecase - define(this, KEY_IGNORE, true) - this._initCache() - } - - _initCache () { - this._ignoreCache = Object.create(null) - this._testCache = Object.create(null) - } - - _addPattern (pattern) { - // #32 - if (pattern && pattern[KEY_IGNORE]) { - this._rules = this._rules.concat(pattern._rules) - this._added = true - return - } - - if (checkPattern(pattern)) { - const rule = createRule(pattern, this._ignorecase) - this._added = true - this._rules.push(rule) - } - } - - // @param {Array | string | Ignore} pattern - add (pattern) { - this._added = false - - makeArray( - isString(pattern) - ? splitPattern(pattern) - : pattern - ).forEach(this._addPattern, this) - - // Some rules have just added to the ignore, - // making the behavior changed. - if (this._added) { - this._initCache() - } - - return this - } - - // legacy - addPattern (pattern) { - return this.add(pattern) - } - - // | ignored : unignored - // negative | 0:0 | 0:1 | 1:0 | 1:1 - // -------- | ------- | ------- | ------- | -------- - // 0 | TEST | TEST | SKIP | X - // 1 | TESTIF | SKIP | TEST | X - - // - SKIP: always skip - // - TEST: always test - // - TESTIF: only test if checkUnignored - // - X: that never happen - - // @param {boolean} whether should check if the path is unignored, - // setting `checkUnignored` to `false` could reduce additional - // path matching. - - // @returns {TestResult} true if a file is ignored - _testOne (path, checkUnignored) { - let ignored = false - let unignored = false - - this._rules.forEach(rule => { - const {negative} = rule - if ( - unignored === negative && ignored !== unignored - || negative && !ignored && !unignored && !checkUnignored - ) { - return - } - - const matched = rule.regex.test(path) - - if (matched) { - ignored = !negative - unignored = negative - } - }) - - return { - ignored, - unignored - } - } - - // @returns {TestResult} - _test (originalPath, cache, checkUnignored, slices) { - const path = originalPath - // Supports nullable path - && checkPath.convert(originalPath) - - checkPath(path, originalPath, throwError) - - return this._t(path, cache, checkUnignored, slices) - } - - _t (path, cache, checkUnignored, slices) { - if (path in cache) { - return cache[path] - } - - if (!slices) { - // path/to/a.js - // ['path', 'to', 'a.js'] - slices = path.split(SLASH) - } - - slices.pop() - - // If the path has no parent directory, just test it - if (!slices.length) { - return cache[path] = this._testOne(path, checkUnignored) - } - - const parent = this._t( - slices.join(SLASH) + SLASH, - cache, - checkUnignored, - slices - ) - - // If the path contains a parent directory, check the parent first - return cache[path] = parent.ignored - // > It is not possible to re-include a file if a parent directory of - // > that file is excluded. - ? parent - : this._testOne(path, checkUnignored) - } - - ignores (path) { - return this._test(path, this._ignoreCache, false).ignored - } - - createFilter () { - return path => !this.ignores(path) - } - - filter (paths) { - return makeArray(paths).filter(this.createFilter()) - } - - // @returns {TestResult} - test (path) { - return this._test(path, this._testCache, true) - } -} - -const factory = options => new Ignore(options) - -const returnFalse = () => false - -const isPathValid = path => - checkPath(path && checkPath.convert(path), path, returnFalse) - -factory.isPathValid = isPathValid - -// Fixes typescript -factory.default = factory - -module.exports = factory - -// Windows -// -------------------------------------------------------------- -/* istanbul ignore if */ -if ( - // Detect `process` so that it can run in browsers. - typeof process !== 'undefined' - && ( - process.env && process.env.IGNORE_TEST_WIN32 - || process.platform === 'win32' - ) -) { - /* eslint no-control-regex: "off" */ - const makePosix = str => /^\\\\\?\\/.test(str) - || /["<>|\u0000-\u001F]+/u.test(str) - ? str - : str.replace(/\\/g, '/') - - checkPath.convert = makePosix - - // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' - // 'd:\\foo' - const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i - checkPath.isNotRelative = path => - REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) - || isNotRelative(path) -} diff --git a/node_modules/ignore/legacy.js b/node_modules/ignore/legacy.js deleted file mode 100644 index 6ae2bb857..000000000 --- a/node_modules/ignore/legacy.js +++ /dev/null @@ -1,476 +0,0 @@ -"use strict"; - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -// A simple implementation of make-array -function makeArray(subject) { - return Array.isArray(subject) ? subject : [subject]; -} - -var REGEX_TEST_BLANK_LINE = /^\s+$/; -var REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/; -var REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/; -var REGEX_SPLITALL_CRLF = /\r?\n/g; // /foo, -// ./foo, -// ../foo, -// . -// .. - -var REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/; -var SLASH = '/'; -var KEY_IGNORE = typeof Symbol !== 'undefined' ? Symbol["for"]('node-ignore') -/* istanbul ignore next */ -: 'node-ignore'; - -var define = function define(object, key, value) { - return Object.defineProperty(object, key, { - value: value - }); -}; - -var REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g; // Sanitize the range of a regular expression -// The cases are complicated, see test cases for details - -var sanitizeRange = function sanitizeRange(range) { - return range.replace(REGEX_REGEXP_RANGE, function (match, from, to) { - return from.charCodeAt(0) <= to.charCodeAt(0) ? match // Invalid range (out of order) which is ok for gitignore rules but - // fatal for JavaScript regular expression, so eliminate it. - : ''; - }); -}; // > If the pattern ends with a slash, -// > it is removed for the purpose of the following description, -// > but it would only find a match with a directory. -// > In other words, foo/ will match a directory foo and paths underneath it, -// > but will not match a regular file or a symbolic link foo -// > (this is consistent with the way how pathspec works in general in Git). -// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' -// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call -// you could use option `mark: true` with `glob` -// '`foo/`' should not continue with the '`..`' - - -var REPLACERS = [// > Trailing spaces are ignored unless they are quoted with backslash ("\") -[// (a\ ) -> (a ) -// (a ) -> (a) -// (a \ ) -> (a ) -/\\?\s+$/, function (match) { - return match.indexOf('\\') === 0 ? ' ' : ''; -}], // replace (\ ) with ' ' -[/\\\s/g, function () { - return ' '; -}], // Escape metacharacters -// which is written down by users but means special for regular expressions. -// > There are 12 characters with special meanings: -// > - the backslash \, -// > - the caret ^, -// > - the dollar sign $, -// > - the period or dot ., -// > - the vertical bar or pipe symbol |, -// > - the question mark ?, -// > - the asterisk or star *, -// > - the plus sign +, -// > - the opening parenthesis (, -// > - the closing parenthesis ), -// > - and the opening square bracket [, -// > - the opening curly brace {, -// > These special characters are often called "metacharacters". -[/[\\^$.|*+(){]/g, function (match) { - return "\\".concat(match); -}], [// > [abc] matches any character inside the brackets -// > (in this case a, b, or c); -/\[([^\]/]*)($|\])/g, function (match, p1, p2) { - return p2 === ']' ? "[".concat(sanitizeRange(p1), "]") : "\\".concat(match); -}], [// > a question mark (?) matches a single character -/(?!\\)\?/g, function () { - return '[^/]'; -}], // leading slash -[// > A leading slash matches the beginning of the pathname. -// > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". -// A leading slash matches the beginning of the pathname -/^\//, function () { - return '^'; -}], // replace special metacharacter slash after the leading slash -[/\//g, function () { - return '\\/'; -}], [// > A leading "**" followed by a slash means match in all directories. -// > For example, "**/foo" matches file or directory "foo" anywhere, -// > the same as pattern "foo". -// > "**/foo/bar" matches file or directory "bar" anywhere that is directly -// > under directory "foo". -// Notice that the '*'s have been replaced as '\\*' -/^\^*\\\*\\\*\\\//, // '**/foo' <-> 'foo' -function () { - return '^(?:.*\\/)?'; -}], // ending -[// 'js' will not match 'js.' -// 'ab' will not match 'abc' -/(?:[^*])$/, // WTF! -// https://git-scm.com/docs/gitignore -// changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) -// which re-fixes #24, #38 -// > If there is a separator at the end of the pattern then the pattern -// > will only match directories, otherwise the pattern can match both -// > files and directories. -// 'js*' will not match 'a.js' -// 'js/' will not match 'a.js' -// 'js' will match 'a.js' and 'a.js/' -function (match) { - return /\/$/.test(match) // foo/ will not match 'foo' - ? "".concat(match, "$") // foo matches 'foo' and 'foo/' - : "".concat(match, "(?=$|\\/$)"); -}], // starting -[// there will be no leading '/' -// (which has been replaced by section "leading slash") -// If starts with '**', adding a '^' to the regular expression also works -/^(?=[^^])/, function startingReplacer() { - // If has a slash `/` at the beginning or middle - return !/\/(?!$)/.test(this) // > Prior to 2.22.1 - // > If the pattern does not contain a slash /, - // > Git treats it as a shell glob pattern - // Actually, if there is only a trailing slash, - // git also treats it as a shell glob pattern - // After 2.22.1 (compatible but clearer) - // > If there is a separator at the beginning or middle (or both) - // > of the pattern, then the pattern is relative to the directory - // > level of the particular .gitignore file itself. - // > Otherwise the pattern may also match at any level below - // > the .gitignore level. - ? '(?:^|\\/)' // > Otherwise, Git treats the pattern as a shell glob suitable for - // > consumption by fnmatch(3) - : '^'; -}], // two globstars -[// Use lookahead assertions so that we could match more than one `'/**'` -/\\\/\\\*\\\*(?=\\\/|$)/g, // Zero, one or several directories -// should not use '*', or it will be replaced by the next replacer -// Check if it is not the last `'/**'` -function (_, index, str) { - return index + 6 < str.length // case: /**/ - // > A slash followed by two consecutive asterisks then a slash matches - // > zero or more directories. - // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. - // '/**/' - ? '(?:\\/[^\\/]+)*' // case: /** - // > A trailing `"/**"` matches everything inside. - // #21: everything inside but it should not include the current folder - : '\\/.+'; -}], // intermediate wildcards -[// Never replace escaped '*' -// ignore rule '\*' will match the path '*' -// 'abc.*/' -> go -// 'abc.*' -> skip this rule -/(^|[^\\]+)\\\*(?=.+)/g, // '*.js' matches '.js' -// '*.js' doesn't match 'abc' -function (_, p1) { - return "".concat(p1, "[^\\/]*"); -}], // trailing wildcard -[/(\^|\\\/)?\\\*$/, function (_, p1) { - var prefix = p1 // '\^': - // '/*' does not match '' - // '/*' does not match everything - // '\\\/': - // 'abc/*' does not match 'abc/' - ? "".concat(p1, "[^/]+") // 'a*' matches 'a' - // 'a*' matches 'aa' - : '[^/]*'; - return "".concat(prefix, "(?=$|\\/$)"); -}], [// unescape -/\\\\\\/g, function () { - return '\\'; -}]]; // A simple cache, because an ignore rule only has only one certain meaning - -var regexCache = Object.create(null); // @param {pattern} - -var makeRegex = function makeRegex(pattern, negative, ignorecase) { - var r = regexCache[pattern]; - - if (r) { - return r; - } // const replacers = negative - // ? NEGATIVE_REPLACERS - // : POSITIVE_REPLACERS - - - var source = REPLACERS.reduce(function (prev, current) { - return prev.replace(current[0], current[1].bind(pattern)); - }, pattern); - return regexCache[pattern] = ignorecase ? new RegExp(source, 'i') : new RegExp(source); -}; - -var isString = function isString(subject) { - return typeof subject === 'string'; -}; // > A blank line matches no files, so it can serve as a separator for readability. - - -var checkPattern = function checkPattern(pattern) { - return pattern && isString(pattern) && !REGEX_TEST_BLANK_LINE.test(pattern) // > A line starting with # serves as a comment. - && pattern.indexOf('#') !== 0; -}; - -var splitPattern = function splitPattern(pattern) { - return pattern.split(REGEX_SPLITALL_CRLF); -}; - -var IgnoreRule = function IgnoreRule(origin, pattern, negative, regex) { - _classCallCheck(this, IgnoreRule); - - this.origin = origin; - this.pattern = pattern; - this.negative = negative; - this.regex = regex; -}; - -var createRule = function createRule(pattern, ignorecase) { - var origin = pattern; - var negative = false; // > An optional prefix "!" which negates the pattern; - - if (pattern.indexOf('!') === 0) { - negative = true; - pattern = pattern.substr(1); - } - - pattern = pattern // > Put a backslash ("\") in front of the first "!" for patterns that - // > begin with a literal "!", for example, `"\!important!.txt"`. - .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') // > Put a backslash ("\") in front of the first hash for patterns that - // > begin with a hash. - .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#'); - var regex = makeRegex(pattern, negative, ignorecase); - return new IgnoreRule(origin, pattern, negative, regex); -}; - -var throwError = function throwError(message, Ctor) { - throw new Ctor(message); -}; - -var checkPath = function checkPath(path, originalPath, doThrow) { - if (!isString(path)) { - return doThrow("path must be a string, but got `".concat(originalPath, "`"), TypeError); - } // We don't know if we should ignore '', so throw - - - if (!path) { - return doThrow("path must not be empty", TypeError); - } // Check if it is a relative path - - - if (checkPath.isNotRelative(path)) { - var r = '`path.relative()`d'; - return doThrow("path should be a ".concat(r, " string, but got \"").concat(originalPath, "\""), RangeError); - } - - return true; -}; - -var isNotRelative = function isNotRelative(path) { - return REGEX_TEST_INVALID_PATH.test(path); -}; - -checkPath.isNotRelative = isNotRelative; - -checkPath.convert = function (p) { - return p; -}; - -var Ignore = -/*#__PURE__*/ -function () { - function Ignore() { - var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, - _ref$ignorecase = _ref.ignorecase, - ignorecase = _ref$ignorecase === void 0 ? true : _ref$ignorecase; - - _classCallCheck(this, Ignore); - - this._rules = []; - this._ignorecase = ignorecase; - define(this, KEY_IGNORE, true); - - this._initCache(); - } - - _createClass(Ignore, [{ - key: "_initCache", - value: function _initCache() { - this._ignoreCache = Object.create(null); - this._testCache = Object.create(null); - } - }, { - key: "_addPattern", - value: function _addPattern(pattern) { - // #32 - if (pattern && pattern[KEY_IGNORE]) { - this._rules = this._rules.concat(pattern._rules); - this._added = true; - return; - } - - if (checkPattern(pattern)) { - var rule = createRule(pattern, this._ignorecase); - this._added = true; - - this._rules.push(rule); - } - } // @param {Array | string | Ignore} pattern - - }, { - key: "add", - value: function add(pattern) { - this._added = false; - makeArray(isString(pattern) ? splitPattern(pattern) : pattern).forEach(this._addPattern, this); // Some rules have just added to the ignore, - // making the behavior changed. - - if (this._added) { - this._initCache(); - } - - return this; - } // legacy - - }, { - key: "addPattern", - value: function addPattern(pattern) { - return this.add(pattern); - } // | ignored : unignored - // negative | 0:0 | 0:1 | 1:0 | 1:1 - // -------- | ------- | ------- | ------- | -------- - // 0 | TEST | TEST | SKIP | X - // 1 | TESTIF | SKIP | TEST | X - // - SKIP: always skip - // - TEST: always test - // - TESTIF: only test if checkUnignored - // - X: that never happen - // @param {boolean} whether should check if the path is unignored, - // setting `checkUnignored` to `false` could reduce additional - // path matching. - // @returns {TestResult} true if a file is ignored - - }, { - key: "_testOne", - value: function _testOne(path, checkUnignored) { - var ignored = false; - var unignored = false; - - this._rules.forEach(function (rule) { - var negative = rule.negative; - - if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) { - return; - } - - var matched = rule.regex.test(path); - - if (matched) { - ignored = !negative; - unignored = negative; - } - }); - - return { - ignored: ignored, - unignored: unignored - }; - } // @returns {TestResult} - - }, { - key: "_test", - value: function _test(originalPath, cache, checkUnignored, slices) { - var path = originalPath // Supports nullable path - && checkPath.convert(originalPath); - checkPath(path, originalPath, throwError); - return this._t(path, cache, checkUnignored, slices); - } - }, { - key: "_t", - value: function _t(path, cache, checkUnignored, slices) { - if (path in cache) { - return cache[path]; - } - - if (!slices) { - // path/to/a.js - // ['path', 'to', 'a.js'] - slices = path.split(SLASH); - } - - slices.pop(); // If the path has no parent directory, just test it - - if (!slices.length) { - return cache[path] = this._testOne(path, checkUnignored); - } - - var parent = this._t(slices.join(SLASH) + SLASH, cache, checkUnignored, slices); // If the path contains a parent directory, check the parent first - - - return cache[path] = parent.ignored // > It is not possible to re-include a file if a parent directory of - // > that file is excluded. - ? parent : this._testOne(path, checkUnignored); - } - }, { - key: "ignores", - value: function ignores(path) { - return this._test(path, this._ignoreCache, false).ignored; - } - }, { - key: "createFilter", - value: function createFilter() { - var _this = this; - - return function (path) { - return !_this.ignores(path); - }; - } - }, { - key: "filter", - value: function filter(paths) { - return makeArray(paths).filter(this.createFilter()); - } // @returns {TestResult} - - }, { - key: "test", - value: function test(path) { - return this._test(path, this._testCache, true); - } - }]); - - return Ignore; -}(); - -var factory = function factory(options) { - return new Ignore(options); -}; - -var returnFalse = function returnFalse() { - return false; -}; - -var isPathValid = function isPathValid(path) { - return checkPath(path && checkPath.convert(path), path, returnFalse); -}; - -factory.isPathValid = isPathValid; // Fixes typescript - -factory["default"] = factory; -module.exports = factory; // Windows -// -------------------------------------------------------------- - -/* istanbul ignore if */ - -if ( // Detect `process` so that it can run in browsers. -typeof process !== 'undefined' && (process.env && process.env.IGNORE_TEST_WIN32 || process.platform === 'win32')) { - /* eslint no-control-regex: "off" */ - var makePosix = function makePosix(str) { - return /^\\\\\?\\/.test(str) || /[\0-\x1F"<>\|]+/.test(str) ? str : str.replace(/\\/g, '/'); - }; - - checkPath.convert = makePosix; // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' - // 'd:\\foo' - - var REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i; - - checkPath.isNotRelative = function (path) { - return REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) || isNotRelative(path); - }; -} diff --git a/node_modules/ignore/package.json b/node_modules/ignore/package.json deleted file mode 100644 index 9641512d4..000000000 --- a/node_modules/ignore/package.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "_from": "ignore@^5.0.5", - "_id": "ignore@5.1.4", - "_inBundle": false, - "_integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", - "_location": "/ignore", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "ignore@^5.0.5", - "name": "ignore", - "escapedName": "ignore", - "rawSpec": "^5.0.5", - "saveSpec": null, - "fetchSpec": "^5.0.5" - }, - "_requiredBy": [ - "/glob-gitignore" - ], - "_resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "_shasum": "84b7b3dbe64552b6ef0eca99f6743dbec6d97adf", - "_spec": "ignore@^5.0.5", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob-gitignore", - "author": { - "name": "kael" - }, - "bugs": { - "url": "https://github.com/kaelzhang/node-ignore/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Ignore is a manager and filter for .gitignore rules, the one used by eslint, gitbook and many others.", - "devDependencies": { - "@babel/cli": "^7.5.5", - "@babel/core": "^7.5.5", - "@babel/preset-env": "^7.5.5", - "codecov": "^3.5.0", - "debug": "^4.1.1", - "eslint": "^6.1.0", - "eslint-config-ostai": "^3.0.0", - "eslint-plugin-import": "^2.18.2", - "mkdirp": "^0.5.1", - "pre-suf": "^1.1.1", - "rimraf": "^2.7.0", - "spawn-sync": "^2.0.0", - "tap": "^14.6.1", - "tmp": "0.1.0", - "typescript": "^3.5.3" - }, - "engines": { - "node": ">= 4" - }, - "files": [ - "legacy.js", - "index.js", - "index.d.ts", - "LICENSE-MIT" - ], - "homepage": "https://github.com/kaelzhang/node-ignore#readme", - "keywords": [ - "ignore", - ".gitignore", - "gitignore", - "npmignore", - "rules", - "manager", - "filter", - "regexp", - "regex", - "fnmatch", - "glob", - "asterisks", - "regular-expression" - ], - "license": "MIT", - "name": "ignore", - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/kaelzhang/node-ignore.git" - }, - "scripts": { - "build": "babel -o legacy.js index.js", - "posttest": "tap --coverage-report=html && codecov", - "prepublishOnly": "npm run build", - "test": "npm run test:only", - "test:cases": "tap test/*.js --coverage", - "test:git": "tap test/git-check-ignore.js", - "test:ignore": "tap test/ignore.js", - "test:lint": "eslint .", - "test:only": "npm run test:lint && npm run test:tsc && npm run test:ts && npm run test:cases", - "test:others": "tap test/others.js", - "test:ts": "node ./test/ts/simple.js", - "test:tsc": "tsc ./test/ts/simple.ts --lib ES6", - "test:win32": "IGNORE_TEST_WIN32=1 npm run test" - }, - "version": "5.1.4" -} diff --git a/node_modules/inflight/LICENSE b/node_modules/inflight/LICENSE deleted file mode 100644 index 05eeeb88c..000000000 --- a/node_modules/inflight/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/inflight/README.md b/node_modules/inflight/README.md deleted file mode 100644 index 6dc892917..000000000 --- a/node_modules/inflight/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# inflight - -Add callbacks to requests in flight to avoid async duplication - -## USAGE - -```javascript -var inflight = require('inflight') - -// some request that does some stuff -function req(key, callback) { - // key is any random string. like a url or filename or whatever. - // - // will return either a falsey value, indicating that the - // request for this key is already in flight, or a new callback - // which when called will call all callbacks passed to inflightk - // with the same key - callback = inflight(key, callback) - - // If we got a falsey value back, then there's already a req going - if (!callback) return - - // this is where you'd fetch the url or whatever - // callback is also once()-ified, so it can safely be assigned - // to multiple events etc. First call wins. - setTimeout(function() { - callback(null, key) - }, 100) -} - -// only assigns a single setTimeout -// when it dings, all cbs get called -req('foo', cb1) -req('foo', cb2) -req('foo', cb3) -req('foo', cb4) -``` diff --git a/node_modules/inflight/inflight.js b/node_modules/inflight/inflight.js deleted file mode 100644 index 48202b3ca..000000000 --- a/node_modules/inflight/inflight.js +++ /dev/null @@ -1,54 +0,0 @@ -var wrappy = require('wrappy') -var reqs = Object.create(null) -var once = require('once') - -module.exports = wrappy(inflight) - -function inflight (key, cb) { - if (reqs[key]) { - reqs[key].push(cb) - return null - } else { - reqs[key] = [cb] - return makeres(key) - } -} - -function makeres (key) { - return once(function RES () { - var cbs = reqs[key] - var len = cbs.length - var args = slice(arguments) - - // XXX It's somewhat ambiguous whether a new callback added in this - // pass should be queued for later execution if something in the - // list of callbacks throws, or if it should just be discarded. - // However, it's such an edge case that it hardly matters, and either - // choice is likely as surprising as the other. - // As it happens, we do go ahead and schedule it for later execution. - try { - for (var i = 0; i < len; i++) { - cbs[i].apply(null, args) - } - } finally { - if (cbs.length > len) { - // added more in the interim. - // de-zalgo, just in case, but don't call again. - cbs.splice(0, len) - process.nextTick(function () { - RES.apply(null, args) - }) - } else { - delete reqs[key] - } - } - }) -} - -function slice (args) { - var length = args.length - var array = [] - - for (var i = 0; i < length; i++) array[i] = args[i] - return array -} diff --git a/node_modules/inflight/package.json b/node_modules/inflight/package.json deleted file mode 100644 index 91757ad34..000000000 --- a/node_modules/inflight/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "_from": "inflight@^1.0.4", - "_id": "inflight@1.0.6", - "_inBundle": false, - "_integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "_location": "/inflight", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "inflight@^1.0.4", - "name": "inflight", - "escapedName": "inflight", - "rawSpec": "^1.0.4", - "saveSpec": null, - "fetchSpec": "^1.0.4" - }, - "_requiredBy": [ - "/glob" - ], - "_resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "_shasum": "49bd6331d7d02d0c09bc910a1075ba8165b56df9", - "_spec": "inflight@^1.0.4", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "bugs": { - "url": "https://github.com/isaacs/inflight/issues" - }, - "bundleDependencies": false, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - }, - "deprecated": false, - "description": "Add callbacks to requests in flight to avoid async duplication", - "devDependencies": { - "tap": "^7.1.2" - }, - "files": [ - "inflight.js" - ], - "homepage": "https://github.com/isaacs/inflight", - "license": "ISC", - "main": "inflight.js", - "name": "inflight", - "repository": { - "type": "git", - "url": "git+https://github.com/npm/inflight.git" - }, - "scripts": { - "test": "tap test.js --100" - }, - "version": "1.0.6" -} diff --git a/node_modules/inherits/LICENSE b/node_modules/inherits/LICENSE deleted file mode 100644 index dea3013d6..000000000 --- a/node_modules/inherits/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - diff --git a/node_modules/inherits/README.md b/node_modules/inherits/README.md deleted file mode 100644 index b1c566585..000000000 --- a/node_modules/inherits/README.md +++ /dev/null @@ -1,42 +0,0 @@ -Browser-friendly inheritance fully compatible with standard node.js -[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). - -This package exports standard `inherits` from node.js `util` module in -node environment, but also provides alternative browser-friendly -implementation through [browser -field](https://gist.github.com/shtylman/4339901). Alternative -implementation is a literal copy of standard one located in standalone -module to avoid requiring of `util`. It also has a shim for old -browsers with no `Object.create` support. - -While keeping you sure you are using standard `inherits` -implementation in node.js environment, it allows bundlers such as -[browserify](https://github.com/substack/node-browserify) to not -include full `util` package to your client code if all you need is -just `inherits` function. It worth, because browser shim for `util` -package is large and `inherits` is often the single function you need -from it. - -It's recommended to use this package instead of -`require('util').inherits` for any code that has chances to be used -not only in node.js but in browser too. - -## usage - -```js -var inherits = require('inherits'); -// then use exactly as the standard one -``` - -## note on version ~1.0 - -Version ~1.0 had completely different motivation and is not compatible -neither with 2.0 nor with standard node.js `inherits`. - -If you are using version ~1.0 and planning to switch to ~2.0, be -careful: - -* new version uses `super_` instead of `super` for referencing - superclass -* new version overwrites current prototype while old one preserves any - existing fields on it diff --git a/node_modules/inherits/inherits.js b/node_modules/inherits/inherits.js deleted file mode 100644 index f71f2d932..000000000 --- a/node_modules/inherits/inherits.js +++ /dev/null @@ -1,9 +0,0 @@ -try { - var util = require('util'); - /* istanbul ignore next */ - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - /* istanbul ignore next */ - module.exports = require('./inherits_browser.js'); -} diff --git a/node_modules/inherits/inherits_browser.js b/node_modules/inherits/inherits_browser.js deleted file mode 100644 index 86bbb3dc2..000000000 --- a/node_modules/inherits/inherits_browser.js +++ /dev/null @@ -1,27 +0,0 @@ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }) - } - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } - } -} diff --git a/node_modules/inherits/package.json b/node_modules/inherits/package.json deleted file mode 100644 index 654fdc6ac..000000000 --- a/node_modules/inherits/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "_from": "inherits@2", - "_id": "inherits@2.0.4", - "_inBundle": false, - "_integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "_location": "/inherits", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "inherits@2", - "name": "inherits", - "escapedName": "inherits", - "rawSpec": "2", - "saveSpec": null, - "fetchSpec": "2" - }, - "_requiredBy": [ - "/glob" - ], - "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "_shasum": "0fa2c64f932917c3433a0ded55363aae37416b7c", - "_spec": "inherits@2", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob", - "browser": "./inherits_browser.js", - "bugs": { - "url": "https://github.com/isaacs/inherits/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", - "devDependencies": { - "tap": "^14.2.4" - }, - "files": [ - "inherits.js", - "inherits_browser.js" - ], - "homepage": "https://github.com/isaacs/inherits#readme", - "keywords": [ - "inheritance", - "class", - "klass", - "oop", - "object-oriented", - "inherits", - "browser", - "browserify" - ], - "license": "ISC", - "main": "./inherits.js", - "name": "inherits", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/inherits.git" - }, - "scripts": { - "test": "tap" - }, - "version": "2.0.4" -} diff --git a/node_modules/lodash.difference/LICENSE b/node_modules/lodash.difference/LICENSE deleted file mode 100644 index e0c69d560..000000000 --- a/node_modules/lodash.difference/LICENSE +++ /dev/null @@ -1,47 +0,0 @@ -Copyright jQuery Foundation and other contributors - -Based on Underscore.js, copyright Jeremy Ashkenas, -DocumentCloud and Investigative Reporters & Editors - -This software consists of voluntary contributions made by many -individuals. For exact contribution history, see the revision history -available at https://github.com/lodash/lodash - -The following license applies to all parts of this software except as -documented below: - -==== - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -==== - -Copyright and related rights for sample code are waived via CC0. Sample -code is defined as all source code displayed within the prose of the -documentation. - -CC0: http://creativecommons.org/publicdomain/zero/1.0/ - -==== - -Files located in the node_modules and vendor directories are externally -maintained libraries used by this software which have their own -licenses; we recommend you read them, as their terms may differ from the -terms above. diff --git a/node_modules/lodash.difference/README.md b/node_modules/lodash.difference/README.md deleted file mode 100644 index be954fd81..000000000 --- a/node_modules/lodash.difference/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# lodash.difference v4.5.0 - -The [lodash](https://lodash.com/) method `_.difference` exported as a [Node.js](https://nodejs.org/) module. - -## Installation - -Using npm: -```bash -$ {sudo -H} npm i -g npm -$ npm i --save lodash.difference -``` - -In Node.js: -```js -var difference = require('lodash.difference'); -``` - -See the [documentation](https://lodash.com/docs#difference) or [package source](https://github.com/lodash/lodash/blob/4.5.0-npm-packages/lodash.difference) for more details. diff --git a/node_modules/lodash.difference/index.js b/node_modules/lodash.difference/index.js deleted file mode 100644 index 4c0b61f7b..000000000 --- a/node_modules/lodash.difference/index.js +++ /dev/null @@ -1,1170 +0,0 @@ -/** - * lodash (Custom Build) - * Build: `lodash modularize exports="npm" -o ./` - * Copyright jQuery Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ - -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE = 200; - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]'; - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); - -/** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ -function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); -} - -/** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ -function arrayIncludes(array, value) { - var length = array ? array.length : 0; - return !!length && baseIndexOf(array, value, 0) > -1; -} - -/** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ -function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (comparator(value, array[index])) { - return true; - } - } - return false; -} - -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array ? array.length : 0, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; -} - -/** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ -function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; -} - -/** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; -} - -/** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseIndexOf(array, value, fromIndex) { - if (value !== value) { - return baseFindIndex(array, baseIsNaN, fromIndex); - } - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; -} - -/** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ -function baseIsNaN(value) { - return value !== value; -} - -/** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ -function baseUnary(func) { - return function(value) { - return func(value); - }; -} - -/** - * Checks if a cache value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function cacheHas(cache, key) { - return cache.has(key); -} - -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -/** - * Checks if `value` is a host object in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a host object, else `false`. - */ -function isHostObject(value) { - // Many host objects are `Object` objects that can coerce to strings - // despite having improperly defined `toString` methods. - var result = false; - if (value != null && typeof value.toString != 'function') { - try { - result = !!(value + ''); - } catch (e) {} - } - return result; -} - -/** Used for built-in method references. */ -var arrayProto = Array.prototype, - funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var objectToString = objectProto.toString; - -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - -/** Built-in value references. */ -var Symbol = root.Symbol, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - splice = arrayProto.splice, - spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMax = Math.max; - -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'), - nativeCreate = getNative(Object, 'create'); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; -} - -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - return this.has(key) && delete this.__data__[key]; -} - -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} - -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); -} - -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; -} - -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - return true; -} - -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; -} - -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - return getMapData(this, key)['delete'](key); -} - -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} - -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} - -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - getMapData(this, key).set(key, value); - return this; -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -/** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ -function SetCache(values) { - var index = -1, - length = values ? values.length : 0; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } -} - -/** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ -function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; -} - -/** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ -function setCacheHas(value) { - return this.__data__.has(value); -} - -// Add methods to `SetCache`. -SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; -SetCache.prototype.has = setCacheHas; - -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; -} - -/** - * The base implementation of methods like `_.difference` without support - * for excluding multiple arrays or iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - */ -function baseDifference(array, values, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - isCommon = true, - length = array.length, - result = [], - valuesLength = values.length; - - if (!length) { - return result; - } - if (iteratee) { - values = arrayMap(values, baseUnary(iteratee)); - } - if (comparator) { - includes = arrayIncludesWith; - isCommon = false; - } - else if (values.length >= LARGE_ARRAY_SIZE) { - includes = cacheHas; - isCommon = false; - values = new SetCache(values); - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === computed) { - continue outer; - } - } - result.push(value); - } - else if (!includes(values, computed, comparator)) { - result.push(value); - } - } - return result; -} - -/** - * The base implementation of `_.flatten` with support for restricting flattening. - * - * @private - * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. - * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. - * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ -function baseFlatten(array, depth, predicate, isStrict, result) { - var index = -1, - length = array.length; - - predicate || (predicate = isFlattenable); - result || (result = []); - - while (++index < length) { - var value = array[index]; - if (depth > 0 && predicate(value)) { - if (depth > 1) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, depth - 1, predicate, isStrict, result); - } else { - arrayPush(result, value); - } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; -} - -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} - -/** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ -function baseRest(func, start) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = array; - return apply(func, this, otherArgs); - }; -} - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -/** - * Checks if `value` is a flattenable `arguments` object or array. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. - */ -function isFlattenable(value) { - return isArray(value) || isArguments(value) || - !!(spreadableSymbol && value && value[spreadableSymbol]); -} - -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} - -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} - -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to process. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} - -/** - * Creates an array of `array` values not included in the other given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. The order of result values is determined by the - * order they occur in the first array. - * - * **Note:** Unlike `_.pullAll`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.without, _.xor - * @example - * - * _.difference([2, 1], [2, 3]); - * // => [1] - */ -var difference = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) - : []; -}); - -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} - -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -function isArguments(value) { - // Safari 8.1 makes `arguments.callee` enumerable in strict mode. - return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && - (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); -} - -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; - -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); -} - -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); -} - -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 8-9 which returns 'object' for typed array and other constructors. - var tag = isObject(value) ? objectToString.call(value) : ''; - return tag == funcTag || tag == genTag; -} - -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} - -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} - -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return !!value && typeof value == 'object'; -} - -module.exports = difference; diff --git a/node_modules/lodash.difference/package.json b/node_modules/lodash.difference/package.json deleted file mode 100644 index 9a3026422..000000000 --- a/node_modules/lodash.difference/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "_from": "lodash.difference@^4.5.0", - "_id": "lodash.difference@4.5.0", - "_inBundle": false, - "_integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "_location": "/lodash.difference", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "lodash.difference@^4.5.0", - "name": "lodash.difference", - "escapedName": "lodash.difference", - "rawSpec": "^4.5.0", - "saveSpec": null, - "fetchSpec": "^4.5.0" - }, - "_requiredBy": [ - "/glob-gitignore" - ], - "_resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "_shasum": "9ccb4e505d486b91651345772885a2df27fd017c", - "_spec": "lodash.difference@^4.5.0", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob-gitignore", - "author": { - "name": "John-David Dalton", - "email": "john.david.dalton@gmail.com", - "url": "http://allyoucanleet.com/" - }, - "bugs": { - "url": "https://github.com/lodash/lodash/issues" - }, - "bundleDependencies": false, - "contributors": [ - { - "name": "John-David Dalton", - "email": "john.david.dalton@gmail.com", - "url": "http://allyoucanleet.com/" - }, - { - "name": "Blaine Bublitz", - "email": "blaine.bublitz@gmail.com", - "url": "https://github.com/phated" - }, - { - "name": "Mathias Bynens", - "email": "mathias@qiwi.be", - "url": "https://mathiasbynens.be/" - } - ], - "deprecated": false, - "description": "The lodash method `_.difference` exported as a module.", - "homepage": "https://lodash.com/", - "icon": "https://lodash.com/icon.svg", - "keywords": [ - "lodash-modularized", - "difference" - ], - "license": "MIT", - "name": "lodash.difference", - "repository": { - "type": "git", - "url": "git+https://github.com/lodash/lodash.git" - }, - "scripts": { - "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" - }, - "version": "4.5.0" -} diff --git a/node_modules/lodash.union/LICENSE b/node_modules/lodash.union/LICENSE deleted file mode 100644 index e0c69d560..000000000 --- a/node_modules/lodash.union/LICENSE +++ /dev/null @@ -1,47 +0,0 @@ -Copyright jQuery Foundation and other contributors - -Based on Underscore.js, copyright Jeremy Ashkenas, -DocumentCloud and Investigative Reporters & Editors - -This software consists of voluntary contributions made by many -individuals. For exact contribution history, see the revision history -available at https://github.com/lodash/lodash - -The following license applies to all parts of this software except as -documented below: - -==== - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -==== - -Copyright and related rights for sample code are waived via CC0. Sample -code is defined as all source code displayed within the prose of the -documentation. - -CC0: http://creativecommons.org/publicdomain/zero/1.0/ - -==== - -Files located in the node_modules and vendor directories are externally -maintained libraries used by this software which have their own -licenses; we recommend you read them, as their terms may differ from the -terms above. diff --git a/node_modules/lodash.union/README.md b/node_modules/lodash.union/README.md deleted file mode 100644 index 001092dde..000000000 --- a/node_modules/lodash.union/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# lodash.union v4.6.0 - -The [lodash](https://lodash.com/) method `_.union` exported as a [Node.js](https://nodejs.org/) module. - -## Installation - -Using npm: -```bash -$ {sudo -H} npm i -g npm -$ npm i --save lodash.union -``` - -In Node.js: -```js -var union = require('lodash.union'); -``` - -See the [documentation](https://lodash.com/docs#union) or [package source](https://github.com/lodash/lodash/blob/4.6.0-npm-packages/lodash.union) for more details. diff --git a/node_modules/lodash.union/index.js b/node_modules/lodash.union/index.js deleted file mode 100644 index d1eb0305d..000000000 --- a/node_modules/lodash.union/index.js +++ /dev/null @@ -1,1181 +0,0 @@ -/** - * lodash (Custom Build) - * Build: `lodash modularize exports="npm" -o ./` - * Copyright jQuery Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ - -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE = 200; - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0, - MAX_SAFE_INTEGER = 9007199254740991; - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]'; - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); - -/** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ -function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); -} - -/** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ -function arrayIncludes(array, value) { - var length = array ? array.length : 0; - return !!length && baseIndexOf(array, value, 0) > -1; -} - -/** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ -function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (comparator(value, array[index])) { - return true; - } - } - return false; -} - -/** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ -function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; -} - -/** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; -} - -/** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseIndexOf(array, value, fromIndex) { - if (value !== value) { - return baseFindIndex(array, baseIsNaN, fromIndex); - } - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; -} - -/** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ -function baseIsNaN(value) { - return value !== value; -} - -/** - * Checks if a cache value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function cacheHas(cache, key) { - return cache.has(key); -} - -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -/** - * Checks if `value` is a host object in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a host object, else `false`. - */ -function isHostObject(value) { - // Many host objects are `Object` objects that can coerce to strings - // despite having improperly defined `toString` methods. - var result = false; - if (value != null && typeof value.toString != 'function') { - try { - result = !!(value + ''); - } catch (e) {} - } - return result; -} - -/** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ -function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; -} - -/** Used for built-in method references. */ -var arrayProto = Array.prototype, - funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var objectToString = objectProto.toString; - -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - -/** Built-in value references. */ -var Symbol = root.Symbol, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - splice = arrayProto.splice, - spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMax = Math.max; - -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'), - Set = getNative(root, 'Set'), - nativeCreate = getNative(Object, 'create'); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; -} - -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - return this.has(key) && delete this.__data__[key]; -} - -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} - -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); -} - -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; -} - -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - return true; -} - -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; -} - -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - return getMapData(this, key)['delete'](key); -} - -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} - -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} - -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - getMapData(this, key).set(key, value); - return this; -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -/** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ -function SetCache(values) { - var index = -1, - length = values ? values.length : 0; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } -} - -/** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ -function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; -} - -/** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ -function setCacheHas(value) { - return this.__data__.has(value); -} - -// Add methods to `SetCache`. -SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; -SetCache.prototype.has = setCacheHas; - -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; -} - -/** - * The base implementation of `_.flatten` with support for restricting flattening. - * - * @private - * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. - * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. - * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ -function baseFlatten(array, depth, predicate, isStrict, result) { - var index = -1, - length = array.length; - - predicate || (predicate = isFlattenable); - result || (result = []); - - while (++index < length) { - var value = array[index]; - if (depth > 0 && predicate(value)) { - if (depth > 1) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, depth - 1, predicate, isStrict, result); - } else { - arrayPush(result, value); - } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; -} - -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} - -/** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ -function baseRest(func, start) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = array; - return apply(func, this, otherArgs); - }; -} - -/** - * The base implementation of `_.uniqBy` without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ -function baseUniq(array, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - length = array.length, - isCommon = true, - result = [], - seen = result; - - if (comparator) { - isCommon = false; - includes = arrayIncludesWith; - } - else if (length >= LARGE_ARRAY_SIZE) { - var set = iteratee ? null : createSet(array); - if (set) { - return setToArray(set); - } - isCommon = false; - includes = cacheHas; - seen = new SetCache; - } - else { - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (!includes(seen, computed, comparator)) { - if (seen !== result) { - seen.push(computed); - } - result.push(value); - } - } - return result; -} - -/** - * Creates a set object of `values`. - * - * @private - * @param {Array} values The values to add to the set. - * @returns {Object} Returns the new set. - */ -var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { - return new Set(values); -}; - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -/** - * Checks if `value` is a flattenable `arguments` object or array. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. - */ -function isFlattenable(value) { - return isArray(value) || isArguments(value) || - !!(spreadableSymbol && value && value[spreadableSymbol]); -} - -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} - -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} - -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to process. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} - -/** - * Creates an array of unique values, in order, from all given arrays using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.union([2], [1, 2]); - * // => [2, 1] - */ -var union = baseRest(function(arrays) { - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); -}); - -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} - -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -function isArguments(value) { - // Safari 8.1 makes `arguments.callee` enumerable in strict mode. - return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && - (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); -} - -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; - -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); -} - -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); -} - -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 8-9 which returns 'object' for typed array and other constructors. - var tag = isObject(value) ? objectToString.call(value) : ''; - return tag == funcTag || tag == genTag; -} - -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} - -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} - -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return !!value && typeof value == 'object'; -} - -/** - * This method returns `undefined`. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Util - * @example - * - * _.times(2, _.noop); - * // => [undefined, undefined] - */ -function noop() { - // No operation performed. -} - -module.exports = union; diff --git a/node_modules/lodash.union/package.json b/node_modules/lodash.union/package.json deleted file mode 100644 index 7b5ca6bf5..000000000 --- a/node_modules/lodash.union/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "_from": "lodash.union@^4.6.0", - "_id": "lodash.union@4.6.0", - "_inBundle": false, - "_integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "_location": "/lodash.union", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "lodash.union@^4.6.0", - "name": "lodash.union", - "escapedName": "lodash.union", - "rawSpec": "^4.6.0", - "saveSpec": null, - "fetchSpec": "^4.6.0" - }, - "_requiredBy": [ - "/glob-gitignore" - ], - "_resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "_shasum": "48bb5088409f16f1821666641c44dd1aaae3cd88", - "_spec": "lodash.union@^4.6.0", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob-gitignore", - "author": { - "name": "John-David Dalton", - "email": "john.david.dalton@gmail.com", - "url": "http://allyoucanleet.com/" - }, - "bugs": { - "url": "https://github.com/lodash/lodash/issues" - }, - "bundleDependencies": false, - "contributors": [ - { - "name": "John-David Dalton", - "email": "john.david.dalton@gmail.com", - "url": "http://allyoucanleet.com/" - }, - { - "name": "Blaine Bublitz", - "email": "blaine.bublitz@gmail.com", - "url": "https://github.com/phated" - }, - { - "name": "Mathias Bynens", - "email": "mathias@qiwi.be", - "url": "https://mathiasbynens.be/" - } - ], - "deprecated": false, - "description": "The lodash method `_.union` exported as a module.", - "homepage": "https://lodash.com/", - "icon": "https://lodash.com/icon.svg", - "keywords": [ - "lodash-modularized", - "union" - ], - "license": "MIT", - "name": "lodash.union", - "repository": { - "type": "git", - "url": "git+https://github.com/lodash/lodash.git" - }, - "scripts": { - "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" - }, - "version": "4.6.0" -} diff --git a/node_modules/make-array/README.md b/node_modules/make-array/README.md deleted file mode 100644 index b21d4fdf5..000000000 --- a/node_modules/make-array/README.md +++ /dev/null @@ -1,61 +0,0 @@ -[![NPM version](https://badge.fury.io/js/make-array.svg)](http://badge.fury.io/js/make-array) -[![Build Status](https://travis-ci.org/kaelzhang/make-array.svg?branch=master)](https://travis-ci.org/kaelzhang/make-array) - -# make-array - -Creates a real Array from almost anything. - -## Install - -```bash -$ npm i make-array --save -``` - -## Usage - -```js -var makeArray = require('make-array'); -makeArray(); // [] -makeArray(undefined); // [] -makeArray(null); // [] -makeArray(1); // [1] -makeArray([1, 2]); // [1, 2] -makeArray({ - '0': 1, - '1': 2, - length: 2 -}); // [1, 2] - -function foo (){ - return makeArray(arguments); -} - -foo(1, 2, 3); // [1, 2, 3] -``` - -### makeArray(subject, [host]) - -- subject `mixed` things you want to make it an array -- host `Array=` if `host` is specified, the newly-created array will append to the end of the `host` - -Returns `Array`. If `host` is specified, it will return the `host` itself. - -```js -var host = [1, 2]; -function foo(){ - return arguments; -} - -var result = makeArray(foo({}, []), host); -result; // [1, 2, {}, []]; -result === host; // true -``` - -## Changelog - -**1.0.0**: bump version to mark it as stable. - -## License - -MIT - diff --git a/node_modules/make-array/index.js b/node_modules/make-array/index.js deleted file mode 100644 index 37470d3a8..000000000 --- a/node_modules/make-array/index.js +++ /dev/null @@ -1,71 +0,0 @@ -// @param {all} subject -// if nodelist, returns an array which generated from the nodelist -// if Array, returns the array itself -// otherwise, returns an array contains the subject -// @param {Array=} host -module.exports = function (subject, host) { - // false -> [false] - // null -> [] - // undefined -> makeArray() -> [] - if (subject === undefined || subject === null) { - return host || [] - } - - // if is already an array - if (isArray(subject)) { - return host - ? host.concat(subject) - : subject - } - - host || (host = []) - if (isArrayLikeObject(subject)) { - // IE fails on collections and ) - // use subject clone instead of Array.prototype.slice - clonePureArray(subject, host) - - } else { - host.push(subject) - } - - return host -} - -var toString = Object.prototype.toString -function isArray (subject) { - return toString.call(subject) === '[object Array]' -} - -// altered from jQuery -function isArrayLikeObject (subject) { - var length = subject.length - - if ( - typeof subject === 'function' - || Object(subject) !== subject - || typeof length !== 'number' - // `window` already has a property `length` - || 'setInterval' in subject - ) { - return false - } - - return length === 0 - || length > 0 && (length - 1) in subject -} - -/** - * clone an object as a pure subject, and ignore non-number properties - * @param {Array} subject - * @param {Array|Object} host required, receiver which the subject be cloned to - */ -function clonePureArray (subject, host) { - var i = subject.length - var start = host.length - - while (i --) { - host[start + i] = subject[i] - } - - return host -} diff --git a/node_modules/make-array/package.json b/node_modules/make-array/package.json deleted file mode 100644 index 31176ccae..000000000 --- a/node_modules/make-array/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "_from": "make-array@^1.0.5", - "_id": "make-array@1.0.5", - "_inBundle": false, - "_integrity": "sha512-sgK2SAzxT19rWU+qxKUcn6PAh/swiIiz2F8C2cZjLc1z4iwYIfdoihqFIDQ8BDzAGtWPYJ6Sr13K1j/DXynDLA==", - "_location": "/make-array", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "make-array@^1.0.5", - "name": "make-array", - "escapedName": "make-array", - "rawSpec": "^1.0.5", - "saveSpec": null, - "fetchSpec": "^1.0.5" - }, - "_requiredBy": [ - "/glob-gitignore" - ], - "_resolved": "https://registry.npmjs.org/make-array/-/make-array-1.0.5.tgz", - "_shasum": "326a7635c756a9f61ce0b2a6fdd5cc3460419bcb", - "_spec": "make-array@^1.0.5", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob-gitignore", - "author": { - "name": "kael" - }, - "bugs": { - "url": "https://github.com/kaelzhang/make-array/issues" - }, - "bundleDependencies": false, - "cortex": { - "devDependencies": { - "chai": "*" - } - }, - "deprecated": false, - "description": "Creates a real Array from almost anything.", - "devDependencies": { - "chai": "*", - "mocha": "*" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/kaelzhang/make-array#readme", - "keywords": [ - "make-array", - "to-array", - "makearray", - "toarray", - "array", - "iterate" - ], - "license": "MIT", - "main": "index.js", - "name": "make-array", - "repository": { - "type": "git", - "url": "git://github.com/kaelzhang/make-array.git" - }, - "scripts": { - "test": "sh test.sh" - }, - "version": "1.0.5" -} diff --git a/node_modules/minimatch/LICENSE b/node_modules/minimatch/LICENSE deleted file mode 100644 index 19129e315..000000000 --- a/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/minimatch/README.md b/node_modules/minimatch/README.md deleted file mode 100644 index ad72b8133..000000000 --- a/node_modules/minimatch/README.md +++ /dev/null @@ -1,209 +0,0 @@ -# minimatch - -A minimal matching utility. - -[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.svg)](http://travis-ci.org/isaacs/minimatch) - - -This is the matching library used internally by npm. - -It works by converting glob expressions into JavaScript `RegExp` -objects. - -## Usage - -```javascript -var minimatch = require("minimatch") - -minimatch("bar.foo", "*.foo") // true! -minimatch("bar.foo", "*.bar") // false! -minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy! -``` - -## Features - -Supports these glob features: - -* Brace Expansion -* Extended glob matching -* "Globstar" `**` matching - -See: - -* `man sh` -* `man bash` -* `man 3 fnmatch` -* `man 5 gitignore` - -## Minimatch Class - -Create a minimatch object by instantiating the `minimatch.Minimatch` class. - -```javascript -var Minimatch = require("minimatch").Minimatch -var mm = new Minimatch(pattern, options) -``` - -### Properties - -* `pattern` The original pattern the minimatch object represents. -* `options` The options supplied to the constructor. -* `set` A 2-dimensional array of regexp or string expressions. - Each row in the - array corresponds to a brace-expanded pattern. Each item in the row - corresponds to a single path-part. For example, the pattern - `{a,b/c}/d` would expand to a set of patterns like: - - [ [ a, d ] - , [ b, c, d ] ] - - If a portion of the pattern doesn't have any "magic" in it - (that is, it's something like `"foo"` rather than `fo*o?`), then it - will be left as a string rather than converted to a regular - expression. - -* `regexp` Created by the `makeRe` method. A single regular expression - expressing the entire pattern. This is useful in cases where you wish - to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. -* `negate` True if the pattern is negated. -* `comment` True if the pattern is a comment. -* `empty` True if the pattern is `""`. - -### Methods - -* `makeRe` Generate the `regexp` member if necessary, and return it. - Will return `false` if the pattern is invalid. -* `match(fname)` Return true if the filename matches the pattern, or - false otherwise. -* `matchOne(fileArray, patternArray, partial)` Take a `/`-split - filename, and match it against a single row in the `regExpSet`. This - method is mainly for internal use, but is exposed so that it can be - used by a glob-walker that needs to avoid excessive filesystem calls. - -All other methods are internal, and will be called as necessary. - -### minimatch(path, pattern, options) - -Main export. Tests a path against the pattern using the options. - -```javascript -var isJS = minimatch(file, "*.js", { matchBase: true }) -``` - -### minimatch.filter(pattern, options) - -Returns a function that tests its -supplied argument, suitable for use with `Array.filter`. Example: - -```javascript -var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true})) -``` - -### minimatch.match(list, pattern, options) - -Match against the list of -files, in the style of fnmatch or glob. If nothing is matched, and -options.nonull is set, then return a list containing the pattern itself. - -```javascript -var javascripts = minimatch.match(fileList, "*.js", {matchBase: true})) -``` - -### minimatch.makeRe(pattern, options) - -Make a regular expression object from the pattern. - -## Options - -All options are `false` by default. - -### debug - -Dump a ton of stuff to stderr. - -### nobrace - -Do not expand `{a,b}` and `{1..3}` brace sets. - -### noglobstar - -Disable `**` matching against multiple folder names. - -### dot - -Allow patterns to match filenames starting with a period, even if -the pattern does not explicitly have a period in that spot. - -Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot` -is set. - -### noext - -Disable "extglob" style patterns like `+(a|b)`. - -### nocase - -Perform a case-insensitive match. - -### nonull - -When a match is not found by `minimatch.match`, return a list containing -the pattern itself if this option is set. When not set, an empty list -is returned if there are no matches. - -### matchBase - -If set, then patterns without slashes will be matched -against the basename of the path if it contains slashes. For example, -`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. - -### nocomment - -Suppress the behavior of treating `#` at the start of a pattern as a -comment. - -### nonegate - -Suppress the behavior of treating a leading `!` character as negation. - -### flipNegate - -Returns from negate expressions the same as if they were not negated. -(Ie, true on a hit, false on a miss.) - - -## Comparisons to other fnmatch/glob implementations - -While strict compliance with the existing standards is a worthwhile -goal, some discrepancies exist between minimatch and other -implementations, and are intentional. - -If the pattern starts with a `!` character, then it is negated. Set the -`nonegate` flag to suppress this behavior, and treat leading `!` -characters normally. This is perhaps relevant if you wish to start the -pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` -characters at the start of a pattern will negate the pattern multiple -times. - -If a pattern starts with `#`, then it is treated as a comment, and -will not match anything. Use `\#` to match a literal `#` at the -start of a line, or set the `nocomment` flag to suppress this behavior. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.1, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then minimatch.match returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. diff --git a/node_modules/minimatch/minimatch.js b/node_modules/minimatch/minimatch.js deleted file mode 100644 index 5b5f8cf44..000000000 --- a/node_modules/minimatch/minimatch.js +++ /dev/null @@ -1,923 +0,0 @@ -module.exports = minimatch -minimatch.Minimatch = Minimatch - -var path = { sep: '/' } -try { - path = require('path') -} catch (er) {} - -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = require('brace-expansion') - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} - -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' - -// * => any number of characters -var star = qmark + '*?' - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} - -function minimatch (p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - // "" only matches "" - if (pattern.trim() === '') return p === '' - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } - - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {} - pattern = pattern.trim() - - // windows support: need to use /, not \ - if (path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function () {} - -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return - - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = console.error - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} - -Minimatch.prototype.braceExpand = braceExpand - -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} - } - } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern - - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern') - } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand(pattern) -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long') - } - - var options = this.options - - // shortcuts - if (!options.noglobstar && pattern === '**') return GLOBSTAR - if (pattern === '') return '' - - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue - } - - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case '\\': - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case '(': - if (inClass) { - re += '(' - continue - } - - if (!stateChar) { - re += '\\(' - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } - - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } - - clearStateChar() - re += '|' - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += '\\' + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } - - re += c - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) - - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '.': - case '[': - case '(': addPatternStart = true - } - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] - - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) - - nlLast += nlAfter - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter - - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } - - if (addPatternStart) { - re = patternStart + re - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) { - this.regexp = false - return this.regexp - } - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' - - try { - this.regexp = new RegExp(re, flags) - } catch (ex) { - this.regexp = false - } - return this.regexp -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = match -function match (f, partial) { - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options - - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, 'set', set) - - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) - - this.debug('matchOne', file.length, pattern.length) - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p - } - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') - return emptyFileEnd - } - - // should be unreachable. - throw new Error('wtf?') -} - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} diff --git a/node_modules/minimatch/package.json b/node_modules/minimatch/package.json deleted file mode 100644 index 7e987e1ce..000000000 --- a/node_modules/minimatch/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "_from": "minimatch@^3.0.4", - "_id": "minimatch@3.0.4", - "_inBundle": false, - "_integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "_location": "/minimatch", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "minimatch@^3.0.4", - "name": "minimatch", - "escapedName": "minimatch", - "rawSpec": "^3.0.4", - "saveSpec": null, - "fetchSpec": "^3.0.4" - }, - "_requiredBy": [ - "/glob" - ], - "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "_shasum": "5166e286457f03306064be5497e8dbb0c3d32083", - "_spec": "minimatch@^3.0.4", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me" - }, - "bugs": { - "url": "https://github.com/isaacs/minimatch/issues" - }, - "bundleDependencies": false, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "deprecated": false, - "description": "a glob matcher in javascript", - "devDependencies": { - "tap": "^10.3.2" - }, - "engines": { - "node": "*" - }, - "files": [ - "minimatch.js" - ], - "homepage": "https://github.com/isaacs/minimatch#readme", - "license": "ISC", - "main": "minimatch.js", - "name": "minimatch", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/minimatch.git" - }, - "scripts": { - "postpublish": "git push origin --all; git push origin --tags", - "postversion": "npm publish", - "preversion": "npm test", - "test": "tap test/*.js --cov" - }, - "version": "3.0.4" -} diff --git a/node_modules/once/LICENSE b/node_modules/once/LICENSE deleted file mode 100644 index 19129e315..000000000 --- a/node_modules/once/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/once/README.md b/node_modules/once/README.md deleted file mode 100644 index 1f1ffca93..000000000 --- a/node_modules/once/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# once - -Only call a function once. - -## usage - -```javascript -var once = require('once') - -function load (file, cb) { - cb = once(cb) - loader.load('file') - loader.once('load', cb) - loader.once('error', cb) -} -``` - -Or add to the Function.prototype in a responsible way: - -```javascript -// only has to be done once -require('once').proto() - -function load (file, cb) { - cb = cb.once() - loader.load('file') - loader.once('load', cb) - loader.once('error', cb) -} -``` - -Ironically, the prototype feature makes this module twice as -complicated as necessary. - -To check whether you function has been called, use `fn.called`. Once the -function is called for the first time the return value of the original -function is saved in `fn.value` and subsequent calls will continue to -return this value. - -```javascript -var once = require('once') - -function load (cb) { - cb = once(cb) - var stream = createStream() - stream.once('data', cb) - stream.once('end', function () { - if (!cb.called) cb(new Error('not found')) - }) -} -``` - -## `once.strict(func)` - -Throw an error if the function is called twice. - -Some functions are expected to be called only once. Using `once` for them would -potentially hide logical errors. - -In the example below, the `greet` function has to call the callback only once: - -```javascript -function greet (name, cb) { - // return is missing from the if statement - // when no name is passed, the callback is called twice - if (!name) cb('Hello anonymous') - cb('Hello ' + name) -} - -function log (msg) { - console.log(msg) -} - -// this will print 'Hello anonymous' but the logical error will be missed -greet(null, once(msg)) - -// once.strict will print 'Hello anonymous' and throw an error when the callback will be called the second time -greet(null, once.strict(msg)) -``` diff --git a/node_modules/once/once.js b/node_modules/once/once.js deleted file mode 100644 index 235406736..000000000 --- a/node_modules/once/once.js +++ /dev/null @@ -1,42 +0,0 @@ -var wrappy = require('wrappy') -module.exports = wrappy(once) -module.exports.strict = wrappy(onceStrict) - -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) - - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }) -}) - -function once (fn) { - var f = function () { - if (f.called) return f.value - f.called = true - return f.value = fn.apply(this, arguments) - } - f.called = false - return f -} - -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true - return f.value = fn.apply(this, arguments) - } - var name = fn.name || 'Function wrapped with `once`' - f.onceError = name + " shouldn't be called more than once" - f.called = false - return f -} diff --git a/node_modules/once/package.json b/node_modules/once/package.json deleted file mode 100644 index b55f1857e..000000000 --- a/node_modules/once/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "_from": "once@^1.3.0", - "_id": "once@1.4.0", - "_inBundle": false, - "_integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "_location": "/once", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "once@^1.3.0", - "name": "once", - "escapedName": "once", - "rawSpec": "^1.3.0", - "saveSpec": null, - "fetchSpec": "^1.3.0" - }, - "_requiredBy": [ - "/glob", - "/inflight" - ], - "_resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "_shasum": "583b1aa775961d4b113ac17d9c50baef9dd76bd1", - "_spec": "once@^1.3.0", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "bugs": { - "url": "https://github.com/isaacs/once/issues" - }, - "bundleDependencies": false, - "dependencies": { - "wrappy": "1" - }, - "deprecated": false, - "description": "Run a function exactly one time", - "devDependencies": { - "tap": "^7.0.1" - }, - "directories": { - "test": "test" - }, - "files": [ - "once.js" - ], - "homepage": "https://github.com/isaacs/once#readme", - "keywords": [ - "once", - "function", - "one", - "single" - ], - "license": "ISC", - "main": "once.js", - "name": "once", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/once.git" - }, - "scripts": { - "test": "tap test/*.js" - }, - "version": "1.4.0" -} diff --git a/node_modules/path-is-absolute/index.js b/node_modules/path-is-absolute/index.js deleted file mode 100644 index 22aa6c356..000000000 --- a/node_modules/path-is-absolute/index.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -function posix(path) { - return path.charAt(0) === '/'; -} - -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); - - // UNC paths are always absolute - return Boolean(result[2] || isUnc); -} - -module.exports = process.platform === 'win32' ? win32 : posix; -module.exports.posix = posix; -module.exports.win32 = win32; diff --git a/node_modules/path-is-absolute/license b/node_modules/path-is-absolute/license deleted file mode 100644 index 654d0bfe9..000000000 --- a/node_modules/path-is-absolute/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/node_modules/path-is-absolute/package.json b/node_modules/path-is-absolute/package.json deleted file mode 100644 index f2bb1a36d..000000000 --- a/node_modules/path-is-absolute/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "_from": "path-is-absolute@^1.0.0", - "_id": "path-is-absolute@1.0.1", - "_inBundle": false, - "_integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "_location": "/path-is-absolute", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "path-is-absolute@^1.0.0", - "name": "path-is-absolute", - "escapedName": "path-is-absolute", - "rawSpec": "^1.0.0", - "saveSpec": null, - "fetchSpec": "^1.0.0" - }, - "_requiredBy": [ - "/glob" - ], - "_resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "_shasum": "174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f", - "_spec": "path-is-absolute@^1.0.0", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/path-is-absolute/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Node.js 0.12 path.isAbsolute() ponyfill", - "devDependencies": { - "xo": "^0.16.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/path-is-absolute#readme", - "keywords": [ - "path", - "paths", - "file", - "dir", - "absolute", - "isabsolute", - "is-absolute", - "built-in", - "util", - "utils", - "core", - "ponyfill", - "polyfill", - "shim", - "is", - "detect", - "check" - ], - "license": "MIT", - "name": "path-is-absolute", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/path-is-absolute.git" - }, - "scripts": { - "test": "xo && node test.js" - }, - "version": "1.0.1" -} diff --git a/node_modules/path-is-absolute/readme.md b/node_modules/path-is-absolute/readme.md deleted file mode 100644 index 8dbdf5fcb..000000000 --- a/node_modules/path-is-absolute/readme.md +++ /dev/null @@ -1,59 +0,0 @@ -# path-is-absolute [![Build Status](https://travis-ci.org/sindresorhus/path-is-absolute.svg?branch=master)](https://travis-ci.org/sindresorhus/path-is-absolute) - -> Node.js 0.12 [`path.isAbsolute()`](http://nodejs.org/api/path.html#path_path_isabsolute_path) [ponyfill](https://ponyfill.com) - - -## Install - -``` -$ npm install --save path-is-absolute -``` - - -## Usage - -```js -const pathIsAbsolute = require('path-is-absolute'); - -// Running on Linux -pathIsAbsolute('/home/foo'); -//=> true -pathIsAbsolute('C:/Users/foo'); -//=> false - -// Running on Windows -pathIsAbsolute('C:/Users/foo'); -//=> true -pathIsAbsolute('/home/foo'); -//=> false - -// Running on any OS -pathIsAbsolute.posix('/home/foo'); -//=> true -pathIsAbsolute.posix('C:/Users/foo'); -//=> false -pathIsAbsolute.win32('C:/Users/foo'); -//=> true -pathIsAbsolute.win32('/home/foo'); -//=> false -``` - - -## API - -See the [`path.isAbsolute()` docs](http://nodejs.org/api/path.html#path_path_isabsolute_path). - -### pathIsAbsolute(path) - -### pathIsAbsolute.posix(path) - -POSIX specific version. - -### pathIsAbsolute.win32(path) - -Windows specific version. - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/util.inherits/HISTORY.md b/node_modules/util.inherits/HISTORY.md deleted file mode 100644 index e061a5372..000000000 --- a/node_modules/util.inherits/HISTORY.md +++ /dev/null @@ -1 +0,0 @@ -# History diff --git a/node_modules/util.inherits/README.md b/node_modules/util.inherits/README.md deleted file mode 100644 index 29b690a9d..000000000 --- a/node_modules/util.inherits/README.md +++ /dev/null @@ -1,45 +0,0 @@ -[![Build Status](https://travis-ci.org/kaelzhang/node-util-inherits.svg?branch=master)](https://travis-ci.org/kaelzhang/node-util-inherits) - - - - - -# util-inherits - -util.inherits with compatibility. - -`util-inherits` will try use `Object.setPrototypeOf`, if `Object.setPrototypeOf` is not supported, then `Object.create`, or manipulate prototype. - -- Browser friendly. -- Does not rely on node utilities - -## Install - -```sh -$ npm install util.inherits --save -``` - -## Usage - -```js -const inherits = require('util.inherits') -const {EventEmitter} = require('events') - -function MyClass () { - // code ... -} - -inherits(MyClass, EventEmitter) -``` - -## License - -MIT diff --git a/node_modules/util.inherits/index.js b/node_modules/util.inherits/index.js deleted file mode 100644 index fe15734b6..000000000 --- a/node_modules/util.inherits/index.js +++ /dev/null @@ -1,47 +0,0 @@ -const inherits = typeof Object.setPrototypeOf === 'function' - ? function (ctor, superCtor) { - ctor.super_ = superCtor - Object.setPrototypeOf(ctor.prototype, superCtor.prototype) - } - - : typeof Object.create === 'function' - ? function (ctor, superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }) - } - - : function (ctor, superCtor) { - ctor.super_ = superCtor - function F () {} - F.prototype = superCtor.prototype - ctor.prototype = new F - ctor.prototype.constructor = ctor - } - - -module.exports = function (ctor, superCtor) { - - if (ctor === undefined || ctor === null) { - throw new TypeError('The constructor to "inherits" must not be ' + - 'null or undefined') - } - - if (superCtor === undefined || superCtor === null) { - throw new TypeError('The super constructor to "inherits" must not ' + - 'be null or undefined') - } - - if (superCtor.prototype === undefined) { - throw new TypeError('The super constructor to "inherits" must ' + - 'have a prototype') - } - - inherits(ctor, superCtor) -} diff --git a/node_modules/util.inherits/package.json b/node_modules/util.inherits/package.json deleted file mode 100644 index 9f831d5d8..000000000 --- a/node_modules/util.inherits/package.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "_from": "util.inherits@^1.0.3", - "_id": "util.inherits@1.0.3", - "_inBundle": false, - "_integrity": "sha1-qcYmoNBtNIKdR7pWyrEnjXRfnOY=", - "_location": "/util.inherits", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "util.inherits@^1.0.3", - "name": "util.inherits", - "escapedName": "util.inherits", - "rawSpec": "^1.0.3", - "saveSpec": null, - "fetchSpec": "^1.0.3" - }, - "_requiredBy": [ - "/glob-gitignore" - ], - "_resolved": "https://registry.npmjs.org/util.inherits/-/util.inherits-1.0.3.tgz", - "_shasum": "a9c626a0d06d34829d47ba56cab1278d745f9ce6", - "_spec": "util.inherits@^1.0.3", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\glob-gitignore", - "author": { - "name": "kaelzhang" - }, - "ava": { - "require": "babel-register", - "babel": { - "babelrc": true - }, - "files": [ - "test.js" - ] - }, - "bugs": { - "url": "https://github.com/kaelzhang/node-util-inherits/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "util.inherits with compatibility", - "devDependencies": { - "ava": "^0.16.0", - "babel-plugin-syntax-trailing-function-commas": "^6.13.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-class-properties": "^6.16.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.16.0", - "babel-plugin-transform-exponentiation-operator": "^6.8.0", - "babel-plugin-transform-inline-environment-variables": "^6.8.0", - "babel-plugin-transform-object-rest-spread": "^6.16.0", - "babel-plugin-transform-runtime": "^6.23.0", - "babel-preset-es2015": "^6.16.0", - "babel-register": "^6.24.1" - }, - "engines": { - "node": ">=4" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/kaelzhang/node-util-inherits#readme", - "keywords": [ - "util-inherits", - "inherits", - "class-extends", - "extend", - "legacy" - ], - "license": "MIT", - "main": "index.js", - "name": "util.inherits", - "repository": { - "type": "git", - "url": "git://github.com/kaelzhang/node-util-inherits.git" - }, - "scripts": { - "test": "node --harmony ./node_modules/.bin/ava --verbose --timeout=10s" - }, - "version": "1.0.3" -} diff --git a/node_modules/wrappy/LICENSE b/node_modules/wrappy/LICENSE deleted file mode 100644 index 19129e315..000000000 --- a/node_modules/wrappy/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/wrappy/README.md b/node_modules/wrappy/README.md deleted file mode 100644 index 98eab2522..000000000 --- a/node_modules/wrappy/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# wrappy - -Callback wrapping utility - -## USAGE - -```javascript -var wrappy = require("wrappy") - -// var wrapper = wrappy(wrapperFunction) - -// make sure a cb is called only once -// See also: http://npm.im/once for this specific use case -var once = wrappy(function (cb) { - var called = false - return function () { - if (called) return - called = true - return cb.apply(this, arguments) - } -}) - -function printBoo () { - console.log('boo') -} -// has some rando property -printBoo.iAmBooPrinter = true - -var onlyPrintOnce = once(printBoo) - -onlyPrintOnce() // prints 'boo' -onlyPrintOnce() // does nothing - -// random property is retained! -assert.equal(onlyPrintOnce.iAmBooPrinter, true) -``` diff --git a/node_modules/wrappy/package.json b/node_modules/wrappy/package.json deleted file mode 100644 index c061eb38d..000000000 --- a/node_modules/wrappy/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "_from": "wrappy@1", - "_id": "wrappy@1.0.2", - "_inBundle": false, - "_integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "_location": "/wrappy", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "wrappy@1", - "name": "wrappy", - "escapedName": "wrappy", - "rawSpec": "1", - "saveSpec": null, - "fetchSpec": "1" - }, - "_requiredBy": [ - "/inflight", - "/once" - ], - "_resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "_shasum": "b5243d8f3ec1aa35f1364605bc0d1036e30ab69f", - "_spec": "wrappy@1", - "_where": "C:\\Users\\ShadowMoose\\Documents\\Git\\LoC-Badge\\node_modules\\inflight", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "bugs": { - "url": "https://github.com/npm/wrappy/issues" - }, - "bundleDependencies": false, - "dependencies": {}, - "deprecated": false, - "description": "Callback wrapping utility", - "devDependencies": { - "tap": "^2.3.1" - }, - "directories": { - "test": "test" - }, - "files": [ - "wrappy.js" - ], - "homepage": "https://github.com/npm/wrappy", - "license": "ISC", - "main": "wrappy.js", - "name": "wrappy", - "repository": { - "type": "git", - "url": "git+https://github.com/npm/wrappy.git" - }, - "scripts": { - "test": "tap --coverage test/*.js" - }, - "version": "1.0.2" -} diff --git a/node_modules/wrappy/wrappy.js b/node_modules/wrappy/wrappy.js deleted file mode 100644 index bb7e7d6fc..000000000 --- a/node_modules/wrappy/wrappy.js +++ /dev/null @@ -1,33 +0,0 @@ -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } -} diff --git a/platform/common/data_comm/BUILD b/platform/common/data_comm/BUILD index 2d887a0f9..f5de8bda3 100644 --- a/platform/common/data_comm/BUILD +++ b/platform/common/data_comm/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/platform/common/data_comm/data_comm.h b/platform/common/data_comm/data_comm.h index 3a568314d..9f7d48821 100644 --- a/platform/common/data_comm/data_comm.h +++ b/platform/common/data_comm/data_comm.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/common/data_comm/network_comm.h b/platform/common/data_comm/network_comm.h index 7a4c3f5d2..2eb682992 100644 --- a/platform/common/data_comm/network_comm.h +++ b/platform/common/data_comm/network_comm.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/common/network/BUILD b/platform/common/network/BUILD index 0545051d9..04790a43a 100644 --- a/platform/common/network/BUILD +++ b/platform/common/network/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/platform/common/network/mock_socket.h b/platform/common/network/mock_socket.h index 69172bc4c..008c1f9bc 100644 --- a/platform/common/network/mock_socket.h +++ b/platform/common/network/mock_socket.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/common/network/network_utils.cpp b/platform/common/network/network_utils.cpp index 0ac783491..24c52beb9 100644 --- a/platform/common/network/network_utils.cpp +++ b/platform/common/network/network_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "network/network_utils.h" diff --git a/platform/common/network/network_utils.h b/platform/common/network/network_utils.h index cd307c3be..512c3054c 100644 --- a/platform/common/network/network_utils.h +++ b/platform/common/network/network_utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/common/network/network_utils_test.cpp b/platform/common/network/network_utils_test.cpp index 967cd03cc..12303c564 100644 --- a/platform/common/network/network_utils_test.cpp +++ b/platform/common/network/network_utils_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "network/network_utils.h" diff --git a/platform/common/network/socket.h b/platform/common/network/socket.h index d6f2df5d9..a0c775338 100644 --- a/platform/common/network/socket.h +++ b/platform/common/network/socket.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/common/network/tcp_socket.cpp b/platform/common/network/tcp_socket.cpp index bbba6ee1e..b541c71dc 100644 --- a/platform/common/network/tcp_socket.cpp +++ b/platform/common/network/tcp_socket.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/common/network/tcp_socket.h" diff --git a/platform/common/network/tcp_socket.h b/platform/common/network/tcp_socket.h index a84d280cc..b894c41c9 100644 --- a/platform/common/network/tcp_socket.h +++ b/platform/common/network/tcp_socket.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/common/network/tcp_socket_test.cpp b/platform/common/network/tcp_socket_test.cpp index 3b8311c0d..db5252348 100644 --- a/platform/common/network/tcp_socket_test.cpp +++ b/platform/common/network/tcp_socket_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/common/network/tcp_socket.h" diff --git a/platform/common/queue/BUILD b/platform/common/queue/BUILD index de2759ba7..110a8228a 100644 --- a/platform/common/queue/BUILD +++ b/platform/common/queue/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/platform/common/queue/batch_queue.h b/platform/common/queue/batch_queue.h index 1657bfe19..ab1cf3ac2 100644 --- a/platform/common/queue/batch_queue.h +++ b/platform/common/queue/batch_queue.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/common/queue/batch_queue_test.cpp b/platform/common/queue/batch_queue_test.cpp index 519da3da0..378a5f9c3 100644 --- a/platform/common/queue/batch_queue_test.cpp +++ b/platform/common/queue/batch_queue_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/common/queue/batch_queue.h" diff --git a/platform/common/queue/blocking_queue.h b/platform/common/queue/blocking_queue.h index 3dd377528..4cf7acfd7 100644 --- a/platform/common/queue/blocking_queue.h +++ b/platform/common/queue/blocking_queue.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/common/queue/lock_free_queue.h b/platform/common/queue/lock_free_queue.h index 5c1a89aa5..1bbfe249b 100644 --- a/platform/common/queue/lock_free_queue.h +++ b/platform/common/queue/lock_free_queue.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once @@ -47,7 +41,7 @@ class LockFreeQueue { bool old_v = true; if (need_notify_.compare_exchange_strong(old_v, false, std::memory_order_acq_rel, - std::memory_order_acq_rel)) { + std::memory_order_acquire)) { std::lock_guard lk(mutex_); cv_.notify_all(); return; diff --git a/platform/common/queue/lock_free_queue_test.cpp b/platform/common/queue/lock_free_queue_test.cpp index a0f6efab6..101d16e25 100644 --- a/platform/common/queue/lock_free_queue_test.cpp +++ b/platform/common/queue/lock_free_queue_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/common/queue/lock_free_queue.h" diff --git a/platform/config/BUILD b/platform/config/BUILD index 85b029d52..cef76adee 100644 --- a/platform/config/BUILD +++ b/platform/config/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/platform/config/resdb_config.cpp b/platform/config/resdb_config.cpp index 8cc355d3c..4c3ff954d 100644 --- a/platform/config/resdb_config.cpp +++ b/platform/config/resdb_config.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/config/resdb_config.h" diff --git a/platform/config/resdb_config.h b/platform/config/resdb_config.h index e4e9f8163..fb56a9dd2 100644 --- a/platform/config/resdb_config.h +++ b/platform/config/resdb_config.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/config/resdb_config_test.cpp b/platform/config/resdb_config_test.cpp index be877c3a3..f480b11f5 100644 --- a/platform/config/resdb_config_test.cpp +++ b/platform/config/resdb_config_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/config/resdb_config.h" diff --git a/platform/config/resdb_config_utils.cpp b/platform/config/resdb_config_utils.cpp index 907bc4854..beae7e957 100644 --- a/platform/config/resdb_config_utils.cpp +++ b/platform/config/resdb_config_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/config/resdb_config_utils.h" diff --git a/platform/config/resdb_config_utils.h b/platform/config/resdb_config_utils.h index aa6974b70..15d77a4bf 100644 --- a/platform/config/resdb_config_utils.h +++ b/platform/config/resdb_config_utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/config/resdb_poc_config.cpp b/platform/config/resdb_poc_config.cpp index 8c8fd414a..c644f391a 100644 --- a/platform/config/resdb_poc_config.cpp +++ b/platform/config/resdb_poc_config.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/config/resdb_poc_config.h" diff --git a/platform/config/resdb_poc_config.h b/platform/config/resdb_poc_config.h index e5895f89b..c0c73a5dd 100644 --- a/platform/config/resdb_poc_config.h +++ b/platform/config/resdb_poc_config.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/checkpoint/BUILD b/platform/consensus/checkpoint/BUILD index 2f107761b..30349b550 100644 --- a/platform/consensus/checkpoint/BUILD +++ b/platform/consensus/checkpoint/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//platform/consensus:__subpackages__"]) cc_library( diff --git a/platform/consensus/checkpoint/checkpoint.h b/platform/consensus/checkpoint/checkpoint.h index cd87e67cb..7a5b967ce 100644 --- a/platform/consensus/checkpoint/checkpoint.h +++ b/platform/consensus/checkpoint/checkpoint.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/checkpoint/mock_checkpoint.h b/platform/consensus/checkpoint/mock_checkpoint.h index 57b3f8397..837d895ca 100644 --- a/platform/consensus/checkpoint/mock_checkpoint.h +++ b/platform/consensus/checkpoint/mock_checkpoint.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/execution/BUILD b/platform/consensus/execution/BUILD index 64a61d969..773e25bc6 100644 --- a/platform/consensus/execution/BUILD +++ b/platform/consensus/execution/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//platform/consensus:__subpackages__"]) cc_library( diff --git a/platform/consensus/execution/duplicate_manager.cpp b/platform/consensus/execution/duplicate_manager.cpp index b2c396fbe..626174b59 100644 --- a/platform/consensus/execution/duplicate_manager.cpp +++ b/platform/consensus/execution/duplicate_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/execution/duplicate_manager.h" diff --git a/platform/consensus/execution/duplicate_manager.h b/platform/consensus/execution/duplicate_manager.h index 69b811cd9..2579196aa 100644 --- a/platform/consensus/execution/duplicate_manager.h +++ b/platform/consensus/execution/duplicate_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/execution/geo_global_executor.cpp b/platform/consensus/execution/geo_global_executor.cpp index 6fd3ef447..1daff7c80 100644 --- a/platform/consensus/execution/geo_global_executor.cpp +++ b/platform/consensus/execution/geo_global_executor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/execution/geo_global_executor.h" diff --git a/platform/consensus/execution/geo_global_executor.h b/platform/consensus/execution/geo_global_executor.h index 7b7f16c89..2a62baefa 100644 --- a/platform/consensus/execution/geo_global_executor.h +++ b/platform/consensus/execution/geo_global_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/execution/geo_global_executor_test.cpp b/platform/consensus/execution/geo_global_executor_test.cpp index 62a80c62a..e911d2aac 100644 --- a/platform/consensus/execution/geo_global_executor_test.cpp +++ b/platform/consensus/execution/geo_global_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/execution/geo_global_executor.h" diff --git a/platform/consensus/execution/geo_transaction_executor.cpp b/platform/consensus/execution/geo_transaction_executor.cpp index c798dd8cc..6b6f2a242 100644 --- a/platform/consensus/execution/geo_transaction_executor.cpp +++ b/platform/consensus/execution/geo_transaction_executor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/execution/geo_transaction_executor.h" diff --git a/platform/consensus/execution/geo_transaction_executor.h b/platform/consensus/execution/geo_transaction_executor.h index c120d3b94..04de32482 100644 --- a/platform/consensus/execution/geo_transaction_executor.h +++ b/platform/consensus/execution/geo_transaction_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/execution/geo_transaction_executor_test.cpp b/platform/consensus/execution/geo_transaction_executor_test.cpp index d263e5232..be7e3acda 100644 --- a/platform/consensus/execution/geo_transaction_executor_test.cpp +++ b/platform/consensus/execution/geo_transaction_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/execution/geo_transaction_executor.h" diff --git a/platform/consensus/execution/mock_geo_global_executor.h b/platform/consensus/execution/mock_geo_global_executor.h index c3676ea52..49e409e3d 100644 --- a/platform/consensus/execution/mock_geo_global_executor.h +++ b/platform/consensus/execution/mock_geo_global_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/execution/system_info.cpp b/platform/consensus/execution/system_info.cpp index 38bc502d8..a12740c8e 100644 --- a/platform/consensus/execution/system_info.cpp +++ b/platform/consensus/execution/system_info.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/execution/system_info.h" diff --git a/platform/consensus/execution/system_info.h b/platform/consensus/execution/system_info.h index ecfde2596..069c772f8 100644 --- a/platform/consensus/execution/system_info.h +++ b/platform/consensus/execution/system_info.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/execution/system_info_test.cpp b/platform/consensus/execution/system_info_test.cpp index c2f938167..4ce86c5dc 100644 --- a/platform/consensus/execution/system_info_test.cpp +++ b/platform/consensus/execution/system_info_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/execution/system_info.h" diff --git a/platform/consensus/execution/transaction_executor.cpp b/platform/consensus/execution/transaction_executor.cpp index 55cd6afbc..fd24da3a3 100644 --- a/platform/consensus/execution/transaction_executor.cpp +++ b/platform/consensus/execution/transaction_executor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/execution/transaction_executor.h" @@ -192,8 +186,8 @@ void TransactionExecutor::OnlyExecute(std::unique_ptr request) { // id:"<proxy_id(); // std::unique_ptr batch_response = // std::make_unique(); - std::unique_ptr response; + global_stats_->GetTransactionDetails(batch_request); if (transaction_manager_) { response = transaction_manager_->ExecuteBatch(batch_request); } @@ -223,6 +217,7 @@ void TransactionExecutor::Execute(std::unique_ptr request, // std::make_unique(); std::unique_ptr response; + global_stats_->GetTransactionDetails(batch_request); if (transaction_manager_ && need_execute) { response = transaction_manager_->ExecuteBatch(batch_request); } @@ -236,6 +231,7 @@ void TransactionExecutor::Execute(std::unique_ptr request, response = std::make_unique(); } + response->set_proxy_id(batch_request.proxy_id()); response->set_createtime(batch_request.createtime()); response->set_local_id(batch_request.local_id()); response->set_hash(batch_request.hash()); diff --git a/platform/consensus/execution/transaction_executor.h b/platform/consensus/execution/transaction_executor.h index 3759a584f..2b111164c 100644 --- a/platform/consensus/execution/transaction_executor.h +++ b/platform/consensus/execution/transaction_executor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/execution/transaction_executor_test.cpp b/platform/consensus/execution/transaction_executor_test.cpp index a48aaf6cc..9abb9ac7f 100644 --- a/platform/consensus/execution/transaction_executor_test.cpp +++ b/platform/consensus/execution/transaction_executor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/execution/transaction_executor.h" diff --git a/platform/consensus/ordering/common/BUILD b/platform/consensus/ordering/common/BUILD index 8a581e54f..0813e522f 100644 --- a/platform/consensus/ordering/common/BUILD +++ b/platform/consensus/ordering/common/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//platform:__subpackages__"]) cc_library( diff --git a/platform/consensus/ordering/common/algorithm/BUILD b/platform/consensus/ordering/common/algorithm/BUILD new file mode 100644 index 000000000..0d7c5d195 --- /dev/null +++ b/platform/consensus/ordering/common/algorithm/BUILD @@ -0,0 +1,29 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +package(default_visibility = ["//platform/consensus/ordering:__subpackages__"]) + +cc_library( + name = "protocol_base", + srcs = ["protocol_base.cpp"], + hdrs = ["protocol_base.h"], + deps = [ + "//common:comm", + "//common/crypto:signature_verifier", + ], +) diff --git a/platform/consensus/ordering/common/algorithm/protocol_base.cpp b/platform/consensus/ordering/common/algorithm/protocol_base.cpp new file mode 100644 index 000000000..cababed4f --- /dev/null +++ b/platform/consensus/ordering/common/algorithm/protocol_base.cpp @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "platform/consensus/ordering/common/algorithm/protocol_base.h" + +#include + +namespace resdb { +namespace common { + +ProtocolBase::ProtocolBase(int id, int f, int total_num, + SingleCallFuncType single_call, + BroadcastCallFuncType broadcast_call, + CommitFuncType commit) + : id_(id), + f_(f), + total_num_(total_num), + single_call_(single_call), + broadcast_call_(broadcast_call), + commit_(commit) { + stop_ = false; +} + +ProtocolBase::ProtocolBase(int id, int f, int total_num) + : ProtocolBase(id, f, total_num, nullptr, nullptr, nullptr) {} + +ProtocolBase::~ProtocolBase() { Stop(); } + +void ProtocolBase::Stop() { stop_ = true; } + +bool ProtocolBase::IsStop() { return stop_; } + +int ProtocolBase::SendMessage(int msg_type, + const google::protobuf::Message& msg, + int node_id) { + return single_call_(msg_type, msg, node_id); +} + +int ProtocolBase::Broadcast(int msg_type, + const google::protobuf::Message& msg) { + return broadcast_call_(msg_type, msg); +} + +int ProtocolBase::Commit(const google::protobuf::Message& msg) { + return commit_(msg); +} + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/algorithm/protocol_base.h b/platform/consensus/ordering/common/algorithm/protocol_base.h new file mode 100644 index 000000000..f8e47052a --- /dev/null +++ b/platform/consensus/ordering/common/algorithm/protocol_base.h @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include + +#include + +#include "common/crypto/signature_verifier.h" + +namespace resdb { +namespace common { + +class ProtocolBase { + public: + typedef std::function + SingleCallFuncType; + typedef std::function + BroadcastCallFuncType; + typedef std::function + CommitFuncType; + + ProtocolBase(int id, int f, int total_num, SingleCallFuncType single_call, + BroadcastCallFuncType broadcast_call, CommitFuncType commit); + + ProtocolBase(int id, int f, int total_num); + + virtual ~ProtocolBase(); + + void Stop(); + + inline void SetSingleCallFunc(SingleCallFuncType single_call) { + single_call_ = single_call; + } + + inline void SetBroadcastCallFunc(BroadcastCallFuncType broadcast_call) { + broadcast_call_ = broadcast_call; + } + + inline void SetCommitFunc(CommitFuncType commit_func) { + commit_ = commit_func; + } + + inline void SetSignatureVerifier(SignatureVerifier* verifier) { + verifier_ = verifier; + } + + protected: + int SendMessage(int msg_type, const google::protobuf::Message& msg, + int node_id); + int Broadcast(int msg_type, const google::protobuf::Message& msg); + int Commit(const google::protobuf::Message& msg); + + bool IsStop(); + + protected: + int id_; + int f_; + int total_num_; + std::function + single_call_; + std::function broadcast_call_; + std::function commit_; + std::atomic stop_; + + SignatureVerifier* verifier_; +}; + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/BUILD b/platform/consensus/ordering/common/framework/BUILD new file mode 100644 index 000000000..c56c92603 --- /dev/null +++ b/platform/consensus/ordering/common/framework/BUILD @@ -0,0 +1,66 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +package(default_visibility = ["//platform/consensus/ordering:__subpackages__"]) + +cc_library( + name = "consensus", + srcs = ["consensus.cpp"], + hdrs = ["consensus.h"], + deps = [ + ":performance_manager", + ":response_manager", + "//common/utils", + "//executor/common:transaction_manager", + "//platform/consensus/execution:transaction_executor", + "//platform/consensus/ordering/common/algorithm:protocol_base", + "//platform/networkstrate:consensus_manager", + ], +) + +cc_library( + name = "performance_manager", + srcs = ["performance_manager.cpp"], + hdrs = ["performance_manager.h"], + deps = [ + ":transaction_utils", + "//platform/networkstrate:replica_communicator", + "//platform/networkstrate:server_comm", + ], +) + +cc_library( + name = "response_manager", + srcs = ["response_manager.cpp"], + hdrs = ["response_manager.h"], + deps = [ + ":transaction_utils", + "//platform/networkstrate:replica_communicator", + "//platform/networkstrate:server_comm", + ], +) + +cc_library( + name = "transaction_utils", + srcs = ["transaction_utils.cpp"], + hdrs = ["transaction_utils.h"], + visibility = ["//visibility:public"], + deps = [ + "//platform/proto:resdb_cc_proto", + ], +) diff --git a/platform/consensus/ordering/common/framework/consensus.cpp b/platform/consensus/ordering/common/framework/consensus.cpp new file mode 100644 index 000000000..93e00cc84 --- /dev/null +++ b/platform/consensus/ordering/common/framework/consensus.cpp @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "platform/consensus/ordering/common/framework/consensus.h" + +#include +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace common { + +Consensus::Consensus(const ResDBConfig& config, + std::unique_ptr executor) + : ConsensusManager(config), + replica_communicator_(GetBroadCastClient()), + transaction_executor_(std::make_unique( + config, + [&](std::unique_ptr request, + std::unique_ptr resp_msg) { + ResponseMsg(*resp_msg); + }, + nullptr, std::move(executor))) { + LOG(INFO) << "is running is performance mode:" + << config_.IsPerformanceRunning(); + is_stop_ = false; + global_stats_ = Stats::GetGlobalStats(); +} + +void Consensus::Init() { + if (performance_manager_ == nullptr) { + performance_manager_ = + config_.IsPerformanceRunning() + ? std::make_unique( + config_, GetBroadCastClient(), GetSignatureVerifier()) + : nullptr; + } + + if (response_manager_ == nullptr) { + response_manager_ = + !config_.IsPerformanceRunning() + ? std::make_unique(config_, GetBroadCastClient(), + GetSignatureVerifier()) + : nullptr; + } +} + +void Consensus::InitProtocol(ProtocolBase* protocol) { + protocol->SetSingleCallFunc( + [&](int type, const google::protobuf::Message& msg, int node_id) { + return SendMsg(type, msg, node_id); + }); + + protocol->SetBroadcastCallFunc( + [&](int type, const google::protobuf::Message& msg) { + return Broadcast(type, msg); + }); + + protocol->SetCommitFunc( + [&](const google::protobuf::Message& msg) { return CommitMsg(msg); }); +} + +Consensus::~Consensus() { is_stop_ = true; } + +void Consensus::SetPerformanceManager( + std::unique_ptr performance_manager) { + performance_manager_ = std::move(performance_manager); +} + +bool Consensus::IsStop() { return is_stop_; } + +void Consensus::SetupPerformanceDataFunc(std::function func) { + performance_manager_->SetDataFunc(func); +} + +void Consensus::SetCommunicator(ReplicaCommunicator* replica_communicator) { + replica_communicator_ = replica_communicator; +} + +int Consensus::Broadcast(int type, const google::protobuf::Message& msg) { + Request request; + msg.SerializeToString(request.mutable_data()); + request.set_type(Request::TYPE_CUSTOM_CONSENSUS); + request.set_user_type(type); + request.set_sender_id(config_.GetSelfInfo().id()); + + replica_communicator_->BroadCast(request); + return 0; +} + +int Consensus::SendMsg(int type, const google::protobuf::Message& msg, + int node_id) { + Request request; + msg.SerializeToString(request.mutable_data()); + request.set_type(Request::TYPE_CUSTOM_CONSENSUS); + request.set_user_type(type); + request.set_sender_id(config_.GetSelfInfo().id()); + replica_communicator_->SendMessage(request, node_id); + return 0; +} + +std::vector Consensus::GetReplicas() { + return config_.GetReplicaInfos(); +} + +int Consensus::CommitMsg(const google::protobuf::Message& txn) { return 0; } + +// The implementation of PBFT. +int Consensus::ConsensusCommit(std::unique_ptr context, + std::unique_ptr request) { + switch (request->type()) { + case Request::TYPE_CLIENT_REQUEST: + if (config_.IsPerformanceRunning()) { + return performance_manager_->StartEval(); + } + case Request::TYPE_RESPONSE: + if (config_.IsPerformanceRunning()) { + return performance_manager_->ProcessResponseMsg(std::move(context), + std::move(request)); + } + case Request::TYPE_NEW_TXNS: { + return ProcessNewTransaction(std::move(request)); + } + case Request::TYPE_CUSTOM_CONSENSUS: { + return ProcessCustomConsensus(std::move(request)); + } + } + return 0; +} + +int Consensus::ProcessCustomConsensus(std::unique_ptr request) { + return 0; +} + +int Consensus::ProcessNewTransaction(std::unique_ptr request) { + return 0; +} + +int Consensus::ResponseMsg(const BatchUserResponse& batch_resp) { + Request request; + request.set_seq(batch_resp.seq()); + request.set_type(Request::TYPE_RESPONSE); + request.set_sender_id(config_.GetSelfInfo().id()); + request.set_proxy_id(batch_resp.proxy_id()); + batch_resp.SerializeToString(request.mutable_data()); + replica_communicator_->SendMessage(request, request.proxy_id()); + return 0; +} + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/consensus.h b/platform/consensus/ordering/common/framework/consensus.h new file mode 100644 index 000000000..2f2884b89 --- /dev/null +++ b/platform/consensus/ordering/common/framework/consensus.h @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include "executor/common/transaction_manager.h" +#include "platform/consensus/execution/transaction_executor.h" +#include "platform/consensus/ordering/common/algorithm/protocol_base.h" +#include "platform/consensus/ordering/common/framework/performance_manager.h" +#include "platform/consensus/ordering/common/framework/response_manager.h" +#include "platform/networkstrate/consensus_manager.h" + +namespace resdb { +namespace common { + +class Consensus : public ConsensusManager { + public: + Consensus(const ResDBConfig& config, + std::unique_ptr transaction_manager); + virtual ~Consensus(); + + int ConsensusCommit(std::unique_ptr context, + std::unique_ptr request) override; + std::vector GetReplicas() override; + + void SetupPerformanceDataFunc(std::function func); + + void SetCommunicator(ReplicaCommunicator* replica_communicator); + + void InitProtocol(ProtocolBase* protocol); + + protected: + virtual int ProcessCustomConsensus(std::unique_ptr request); + virtual int ProcessNewTransaction(std::unique_ptr request); + virtual int CommitMsg(const google::protobuf::Message& msg); + + protected: + int SendMsg(int type, const google::protobuf::Message& msg, int node_id); + int Broadcast(int type, const google::protobuf::Message& msg); + int ResponseMsg(const BatchUserResponse& batch_resp); + void AsyncSend(); + bool IsStop(); + + protected: + void Init(); + void SetPerformanceManager( + std::unique_ptr performance_manger); + + protected: + ReplicaCommunicator* replica_communicator_; + std::unique_ptr performance_manager_; + std::unique_ptr response_manager_; + std::unique_ptr transaction_executor_; + Stats* global_stats_; + + LockFreeQueue resp_queue_; + std::vector send_thread_; + bool is_stop_; +}; + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/performance_manager.cpp b/platform/consensus/ordering/common/framework/performance_manager.cpp new file mode 100644 index 000000000..c07088f1f --- /dev/null +++ b/platform/consensus/ordering/common/framework/performance_manager.cpp @@ -0,0 +1,276 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "platform/consensus/ordering/common/framework/performance_manager.h" + +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace common { + +using comm::CollectorResultCode; + +PerformanceManager::PerformanceManager( + const ResDBConfig& config, ReplicaCommunicator* replica_communicator, + SignatureVerifier* verifier) + : config_(config), + replica_communicator_(replica_communicator), + batch_queue_("user request"), + verifier_(verifier) { + stop_ = false; + eval_started_ = false; + eval_ready_future_ = eval_ready_promise_.get_future(); + if (config_.GetPublicKeyCertificateInfo() + .public_key() + .public_key_info() + .type() == CertificateKeyInfo::CLIENT) { + for (int i = 0; i < 1; ++i) { + user_req_thread_[i] = + std::thread(&PerformanceManager::BatchProposeMsg, this); + } + } + global_stats_ = Stats::GetGlobalStats(); + send_num_ = 0; + total_num_ = 0; + replica_num_ = config_.GetReplicaNum(); + id_ = config_.GetSelfInfo().id(); + primary_ = id_ % replica_num_; + if (primary_ == 0) primary_ = replica_num_; + local_id_ = 1; + sum_ = 0; +} + +PerformanceManager::~PerformanceManager() { + stop_ = true; + for (int i = 0; i < 16; ++i) { + if (user_req_thread_[i].joinable()) { + user_req_thread_[i].join(); + } + } +} + +int PerformanceManager::GetPrimary() { return primary_; } + +std::unique_ptr PerformanceManager::GenerateUserRequest() { + std::unique_ptr request = std::make_unique(); + request->set_data(data_func_()); + return request; +} + +void PerformanceManager::SetDataFunc(std::function func) { + data_func_ = std::move(func); +} + +int PerformanceManager::StartEval() { + if (eval_started_) { + return 0; + } + eval_started_ = true; + for (int i = 0; i < 100000000; ++i) { + std::unique_ptr queue_item = std::make_unique(); + queue_item->context = nullptr; + queue_item->user_request = GenerateUserRequest(); + batch_queue_.Push(std::move(queue_item)); + if (i == 2000000) { + eval_ready_promise_.set_value(true); + } + } + LOG(WARNING) << "start eval done"; + return 0; +} + +// =================== response ======================== +// handle the response message. If receive f+1 commit messages, send back to the +// user. +int PerformanceManager::ProcessResponseMsg(std::unique_ptr context, + std::unique_ptr request) { + std::unique_ptr response; + // Add the response message, and use the call back to collect the received + // messages. + // The callback will be triggered if it received f+1 messages. + if (request->ret() == -2) { + // LOG(INFO) << "get response fail:" << request->ret(); + send_num_--; + return 0; + } + + // LOG(INFO) << "get response:" << request->seq() << " + // sender:"<sender_id(); + std::unique_ptr batch_response = nullptr; + CollectorResultCode ret = AddResponseMsg( + std::move(request), [&](std::unique_ptr request) { + batch_response = std::move(request); + return; + }); + + if (ret == CollectorResultCode::STATE_CHANGED) { + assert(batch_response); + SendResponseToClient(*batch_response); + } + return ret == CollectorResultCode::INVALID ? -2 : 0; +} + +CollectorResultCode PerformanceManager::AddResponseMsg( + std::unique_ptr request, + std::function)> + response_call_back) { + if (request == nullptr) { + return CollectorResultCode::INVALID; + } + + std::unique_ptr batch_response = + std::make_unique(); + if (!batch_response->ParseFromString(request->data())) { + LOG(ERROR) << "parse response fail:" << request->data().size() + << " seq:" << request->seq(); + return CollectorResultCode::INVALID; + } + + uint64_t seq = batch_response->local_id(); + + bool done = false; + { + int idx = seq % response_set_size_; + std::unique_lock lk(response_lock_[idx]); + if (response_[idx].find(seq) == response_[idx].end()) { + return CollectorResultCode::OK; + } + response_[idx][seq]++; + if (response_[idx][seq] >= config_.GetMinClientReceiveNum()) { + response_[idx].erase(response_[idx].find(seq)); + done = true; + } + } + if (done) { + response_call_back(std::move(batch_response)); + return CollectorResultCode::STATE_CHANGED; + } + return CollectorResultCode::OK; +} + +void PerformanceManager::SendResponseToClient( + const BatchUserResponse& batch_response) { + uint64_t create_time = batch_response.createtime(); + if (create_time > 0) { + uint64_t run_time = GetCurrentTime() - create_time; + LOG(ERROR) << "receive current:" << GetCurrentTime() + << " create time:" << create_time << " run time:" << run_time + << " local id:" << batch_response.local_id(); + global_stats_->AddLatency(run_time); + } + send_num_--; +} + +// =================== request ======================== +int PerformanceManager::BatchProposeMsg() { + LOG(WARNING) << "batch wait time:" << config_.ClientBatchWaitTimeMS() + << " batch num:" << config_.ClientBatchNum() + << " max txn:" << config_.GetMaxProcessTxn(); + std::vector> batch_req; + eval_ready_future_.get(); + bool start = false; + while (!stop_) { + if (send_num_ > config_.GetMaxProcessTxn()) { + usleep(100000); + continue; + } + if (batch_req.size() < config_.ClientBatchNum()) { + std::unique_ptr item = + batch_queue_.Pop(config_.ClientBatchWaitTimeMS()); + if (item == nullptr) { + if (start) { + LOG(ERROR) << "no data"; + } + continue; + } + batch_req.push_back(std::move(item)); + if (batch_req.size() < config_.ClientBatchNum()) { + continue; + } + } + start = true; + DoBatch(batch_req); + batch_req.clear(); + } + return 0; +} + +int PerformanceManager::DoBatch( + const std::vector>& batch_req) { + auto new_request = comm::NewRequest(Request::TYPE_NEW_TXNS, Request(), + config_.GetSelfInfo().id()); + if (new_request == nullptr) { + return -2; + } + + BatchUserRequest batch_request; + for (size_t i = 0; i < batch_req.size(); ++i) { + BatchUserRequest::UserRequest* req = batch_request.add_user_requests(); + *req->mutable_request() = *batch_req[i]->user_request.get(); + req->set_id(i); + } + + batch_request.set_local_id(local_id_++); + + { + int idx = batch_request.local_id() % response_set_size_; + std::unique_lock lk(response_lock_[idx]); + response_[idx][batch_request.local_id()]++; + } + + batch_request.set_proxy_id(config_.GetSelfInfo().id()); + batch_request.set_createtime(GetCurrentTime()); + batch_request.SerializeToString(new_request->mutable_data()); + if (verifier_) { + auto signature_or = verifier_->SignMessage(new_request->data()); + if (!signature_or.ok()) { + LOG(ERROR) << "Sign message fail"; + return -2; + } + *new_request->mutable_data_signature() = *signature_or; + } + + new_request->set_hash(SignatureVerifier::CalculateHash(new_request->data())); + new_request->set_proxy_id(config_.GetSelfInfo().id()); + new_request->set_user_seq(batch_request.local_id()); + + SendMessage(*new_request); + + global_stats_->BroadCastMsg(); + send_num_++; + sum_ += batch_req.size(); + if (total_num_++ == 1000000) { + stop_ = true; + LOG(WARNING) << "total num is done:" << total_num_; + } + if (total_num_ % 1000 == 0) { + LOG(WARNING) << "total num is :" << total_num_; + } + global_stats_->IncClientCall(); + return 0; +} + +void PerformanceManager::SendMessage(const Request& request) { + replica_communicator_->SendMessage(request, GetPrimary()); +} + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/performance_manager.h b/platform/consensus/ordering/common/framework/performance_manager.h new file mode 100644 index 000000000..a34f05739 --- /dev/null +++ b/platform/consensus/ordering/common/framework/performance_manager.h @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include + +#include "platform/config/resdb_config.h" +#include "platform/consensus/ordering/common/framework/transaction_utils.h" +#include "platform/networkstrate/replica_communicator.h" +#include "platform/networkstrate/server_comm.h" +#include "platform/statistic/stats.h" + +namespace resdb { +namespace common { + +class PerformanceManager { + public: + PerformanceManager(const ResDBConfig& config, + ReplicaCommunicator* replica_communicator, + SignatureVerifier* verifier); + + virtual ~PerformanceManager(); + + int StartEval(); + + int ProcessResponseMsg(std::unique_ptr context, + std::unique_ptr request); + void SetDataFunc(std::function func); + + protected: + virtual void SendMessage(const Request& request); + + private: + // Add response messages which will be sent back to the caller + // if there are f+1 same messages. + comm::CollectorResultCode AddResponseMsg( + std::unique_ptr request, + std::function)> call_back); + void SendResponseToClient(const BatchUserResponse& batch_response); + + struct QueueItem { + std::unique_ptr context; + std::unique_ptr user_request; + }; + int DoBatch(const std::vector>& batch_req); + int BatchProposeMsg(); + int GetPrimary(); + std::unique_ptr GenerateUserRequest(); + + protected: + ResDBConfig config_; + ReplicaCommunicator* replica_communicator_; + + private: + LockFreeQueue batch_queue_; + std::thread user_req_thread_[16]; + std::atomic stop_; + Stats* global_stats_; + std::atomic send_num_; + std::mutex mutex_; + std::atomic total_num_; + SignatureVerifier* verifier_; + SignatureInfo sig_; + std::function data_func_; + std::future eval_ready_future_; + std::promise eval_ready_promise_; + std::atomic eval_started_; + std::atomic fail_num_; + static const int response_set_size_ = 6000000; + std::map response_[response_set_size_]; + std::mutex response_lock_[response_set_size_]; + int replica_num_; + int id_; + int primary_; + std::atomic local_id_; + std::atomic sum_; +}; + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/response_manager.cpp b/platform/consensus/ordering/common/framework/response_manager.cpp new file mode 100644 index 000000000..18eb065ac --- /dev/null +++ b/platform/consensus/ordering/common/framework/response_manager.cpp @@ -0,0 +1,236 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "platform/consensus/ordering/common/framework/response_manager.h" + +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace common { + +using namespace resdb::comm; + +ResponseManager::ResponseManager(const ResDBConfig& config, + ReplicaCommunicator* replica_communicator, + SignatureVerifier* verifier) + : config_(config), + replica_communicator_(replica_communicator), + batch_queue_("user request"), + verifier_(verifier) { + stop_ = false; + local_id_ = 1; + + if (config_.GetPublicKeyCertificateInfo() + .public_key() + .public_key_info() + .type() == CertificateKeyInfo::CLIENT || + config_.IsTestMode()) { + user_req_thread_ = std::thread(&ResponseManager::BatchProposeMsg, this); + } + global_stats_ = Stats::GetGlobalStats(); + send_num_ = 0; +} + +ResponseManager::~ResponseManager() { + stop_ = true; + if (user_req_thread_.joinable()) { + user_req_thread_.join(); + } +} + +// use system info +int ResponseManager::GetPrimary() { return 1; } + +int ResponseManager::NewUserRequest(std::unique_ptr context, + std::unique_ptr user_request) { + context->client = nullptr; + + std::unique_ptr queue_item = std::make_unique(); + queue_item->context = std::move(context); + queue_item->user_request = std::move(user_request); + + batch_queue_.Push(std::move(queue_item)); + return 0; +} + +// =================== response ======================== +// handle the response message. If receive f+1 commit messages, send back to the +// caller. +int ResponseManager::ProcessResponseMsg(std::unique_ptr context, + std::unique_ptr request) { + std::unique_ptr response; + // Add the response message, and use the call back to collect the received + // messages. + // The callback will be triggered if it received f+1 messages. + if (request->ret() == -2) { + LOG(ERROR) << "get response fail:" << request->ret(); + send_num_--; + return 0; + } + CollectorResultCode ret = + AddResponseMsg(std::move(request), [&](const Request& request) { + response = std::make_unique(request); + return; + }); + + if (ret == CollectorResultCode::STATE_CHANGED) { + BatchUserResponse batch_response; + if (batch_response.ParseFromString(response->data())) { + SendResponseToClient(batch_response); + } else { + LOG(ERROR) << "parse response fail:"; + } + } + return ret == CollectorResultCode::INVALID ? -2 : 0; +} + +CollectorResultCode ResponseManager::AddResponseMsg( + std::unique_ptr request, + std::function response_call_back) { + if (request == nullptr) { + return CollectorResultCode::INVALID; + } + + int type = request->type(); + uint64_t seq = request->seq(); + bool done = false; + { + int idx = seq % response_set_size_; + std::unique_lock lk(response_lock_[idx]); + if (response_[idx][seq] == -1) { + return CollectorResultCode::OK; + } + response_[idx][seq]++; + if (response_[idx][seq] >= config_.GetMinClientReceiveNum()) { + response_[idx][seq] = -1; + done = true; + } + } + if (done) { + response_call_back(*request); + return CollectorResultCode::STATE_CHANGED; + } + return CollectorResultCode::OK; +} + +void ResponseManager::SendResponseToClient( + const BatchUserResponse& batch_response) { + uint64_t create_time = batch_response.createtime(); + uint64_t local_id = batch_response.local_id(); + if (create_time > 0) { + uint64_t run_time = GetCurrentTime() - create_time; + global_stats_->AddLatency(run_time); + } else { + LOG(ERROR) << "seq:" << local_id << " no resp"; + } + send_num_--; +} + +// =================== request ======================== +int ResponseManager::BatchProposeMsg() { + LOG(INFO) << "batch wait time:" << config_.ClientBatchWaitTimeMS() + << " batch num:" << config_.ClientBatchNum(); + std::vector> batch_req; + while (!stop_) { + if (send_num_ > config_.GetMaxProcessTxn()) { + LOG(ERROR) << "send num too high, wait:" << send_num_; + usleep(100); + continue; + } + if (batch_req.size() < config_.ClientBatchNum()) { + std::unique_ptr item = + batch_queue_.Pop(config_.ClientBatchWaitTimeMS()); + if (item != nullptr) { + batch_req.push_back(std::move(item)); + if (batch_req.size() < config_.ClientBatchNum()) { + continue; + } + } + } + if (batch_req.empty()) { + continue; + } + int ret = DoBatch(batch_req); + batch_req.clear(); + if (ret != 0) { + Response response; + response.set_result(Response::ERROR); + for (size_t i = 0; i < batch_req.size(); ++i) { + if (batch_req[i]->context && batch_req[i]->context->client) { + int ret = batch_req[i]->context->client->SendRawMessage(response); + if (ret) { + LOG(ERROR) << "send resp" << response.DebugString() + << " fail ret:" << ret; + } + } + } + } + } + return 0; +} + +int ResponseManager::DoBatch( + const std::vector>& batch_req) { + auto new_request = + NewRequest(Request::TYPE_NEW_TXNS, Request(), config_.GetSelfInfo().id()); + if (new_request == nullptr) { + return -2; + } + std::vector> context_list; + + BatchUserRequest batch_request; + for (size_t i = 0; i < batch_req.size(); ++i) { + BatchUserRequest::UserRequest* req = batch_request.add_user_requests(); + *req->mutable_request() = *batch_req[i]->user_request.get(); + *req->mutable_signature() = batch_req[i]->context->signature; + req->set_id(i); + context_list.push_back(std::move(batch_req[i]->context)); + } + + if (!config_.IsPerformanceRunning()) { + LOG(ERROR) << "add context list:" << new_request->seq() + << " list size:" << context_list.size(); + batch_request.set_local_id(local_id_); + } + batch_request.set_createtime(GetCurrentTime()); + std::string data; + batch_request.SerializeToString(&data); + if (verifier_) { + auto signature_or = verifier_->SignMessage(data); + if (!signature_or.ok()) { + LOG(ERROR) << "Sign message fail"; + return -2; + } + *new_request->mutable_data_signature() = *signature_or; + } + + batch_request.SerializeToString(new_request->mutable_data()); + new_request->set_hash(SignatureVerifier::CalculateHash(new_request->data())); + new_request->set_proxy_id(config_.GetSelfInfo().id()); + replica_communicator_->SendMessage(*new_request, GetPrimary()); + send_num_++; + LOG(INFO) << "send msg to primary:" << GetPrimary() + << " batch size:" << batch_req.size(); + return 0; +} + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/response_manager.h b/platform/consensus/ordering/common/framework/response_manager.h new file mode 100644 index 000000000..fef43dd80 --- /dev/null +++ b/platform/consensus/ordering/common/framework/response_manager.h @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include "platform/config/resdb_config.h" +#include "platform/consensus/ordering/common/framework/transaction_utils.h" +#include "platform/networkstrate/replica_communicator.h" +#include "platform/networkstrate/server_comm.h" +#include "platform/statistic/stats.h" + +namespace resdb { +namespace common { + +class ResponseManager { + public: + ResponseManager(const ResDBConfig& config, + ReplicaCommunicator* replica_communicator, + SignatureVerifier* verifier); + + ~ResponseManager(); + + std::vector> FetchContextList(uint64_t id); + + int NewUserRequest(std::unique_ptr context, + std::unique_ptr user_request); + + int ProcessResponseMsg(std::unique_ptr context, + std::unique_ptr request); + + private: + // Add response messages which will be sent back to the caller + // if there are f+1 same messages. + comm::CollectorResultCode AddResponseMsg( + std::unique_ptr request, + std::function call_back); + void SendResponseToClient(const BatchUserResponse& batch_response); + + struct QueueItem { + std::unique_ptr context; + std::unique_ptr user_request; + }; + int DoBatch(const std::vector>& batch_req); + int BatchProposeMsg(); + int GetPrimary(); + + private: + ResDBConfig config_; + ReplicaCommunicator* replica_communicator_; + LockFreeQueue batch_queue_; + std::thread user_req_thread_; + std::atomic stop_; + uint64_t local_id_ = 0; + Stats* global_stats_; + std::atomic send_num_; + SignatureVerifier* verifier_; + static const int response_set_size_ = 6000000; + std::map response_[response_set_size_]; + std::mutex response_lock_[response_set_size_]; +}; + +} // namespace common +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/transaction_utils.cpp b/platform/consensus/ordering/common/framework/transaction_utils.cpp new file mode 100644 index 000000000..9daca0209 --- /dev/null +++ b/platform/consensus/ordering/common/framework/transaction_utils.cpp @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "platform/consensus/ordering/common/framework/transaction_utils.h" + +namespace resdb { +namespace comm { + +std::unique_ptr NewRequest(Request::Type type, const Request& request, + int sender_id) { + auto new_request = std::make_unique(request); + new_request->set_type(type); + new_request->set_sender_id(sender_id); + return new_request; +} + +std::unique_ptr NewRequest(Request::Type type, const Request& request, + int sender_id, int region_id) { + auto new_request = std::make_unique(request); + new_request->set_type(type); + new_request->set_sender_id(sender_id); + new_request->mutable_region_info()->set_region_id(region_id); + return new_request; +} + +} // namespace comm +} // namespace resdb diff --git a/platform/consensus/ordering/common/framework/transaction_utils.h b/platform/consensus/ordering/common/framework/transaction_utils.h new file mode 100644 index 000000000..57bb8d354 --- /dev/null +++ b/platform/consensus/ordering/common/framework/transaction_utils.h @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once +#include "platform/proto/replica_info.pb.h" +#include "platform/proto/resdb.pb.h" + +namespace resdb { +namespace comm { + +enum CollectorResultCode { + INVALID = -2, + OK = 0, + STATE_CHANGED = 1, +}; + +std::unique_ptr NewRequest(Request::Type type, const Request& request, + int sender_id); + +std::unique_ptr NewRequest(Request::Type type, const Request& request, + int sender_id, int region_info); +} // namespace comm +} // namespace resdb diff --git a/platform/consensus/ordering/common/transaction_utils.cpp b/platform/consensus/ordering/common/transaction_utils.cpp index e560cfc9c..fea180a0b 100644 --- a/platform/consensus/ordering/common/transaction_utils.cpp +++ b/platform/consensus/ordering/common/transaction_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/common/transaction_utils.h" diff --git a/platform/consensus/ordering/common/transaction_utils.h b/platform/consensus/ordering/common/transaction_utils.h index b0d6aab29..151b431c3 100644 --- a/platform/consensus/ordering/common/transaction_utils.h +++ b/platform/consensus/ordering/common/transaction_utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/geo_pbft/BUILD b/platform/consensus/ordering/geo_pbft/BUILD index 652c9d206..4bc568dd5 100644 --- a/platform/consensus/ordering/geo_pbft/BUILD +++ b/platform/consensus/ordering/geo_pbft/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:private"]) cc_library( diff --git a/platform/consensus/ordering/geo_pbft/README.md b/platform/consensus/ordering/geo_pbft/README.md index 15faa978d..c0848e9e2 100644 --- a/platform/consensus/ordering/geo_pbft/README.md +++ b/platform/consensus/ordering/geo_pbft/README.md @@ -1,4 +1,23 @@ + + # GeoBFT Consensus Structure Diagram
-
\ No newline at end of file +
diff --git a/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.cpp b/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.cpp index 4317a3960..fc3d7fc5e 100644 --- a/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.cpp +++ b/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h" diff --git a/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h b/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h index 9cb3edafd..42fbf3ae7 100644 --- a/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h +++ b/platform/consensus/ordering/geo_pbft/consensus_manager_geo_pbft.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.cpp b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.cpp index acc10b5f2..61c5cf37e 100644 --- a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.cpp +++ b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h" diff --git a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h index c059da5e2..43fc7c76d 100644 --- a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h +++ b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment_test.cpp b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment_test.cpp index 6cc66585b..0c9c31c45 100644 --- a/platform/consensus/ordering/geo_pbft/geo_pbft_commitment_test.cpp +++ b/platform/consensus/ordering/geo_pbft/geo_pbft_commitment_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/geo_pbft/geo_pbft_commitment.h" diff --git a/platform/consensus/ordering/geo_pbft/hash_set.h b/platform/consensus/ordering/geo_pbft/hash_set.h index 2ee556bbb..e608e7955 100644 --- a/platform/consensus/ordering/geo_pbft/hash_set.h +++ b/platform/consensus/ordering/geo_pbft/hash_set.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/BUILD b/platform/consensus/ordering/pbft/BUILD index 300c96a90..6f4fdff70 100644 --- a/platform/consensus/ordering/pbft/BUILD +++ b/platform/consensus/ordering/pbft/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:private"]) cc_library( @@ -61,7 +80,7 @@ cc_library( ":lock_free_collector_pool", ":transaction_collector", ":transaction_utils", - "//chain/storage:txn_memory_db", + "//chain/state:chain_state", "//executor/common:transaction_manager", "//platform/config:resdb_config", "//platform/networkstrate:server_comm", @@ -114,7 +133,7 @@ cc_library( hdrs = ["checkpoint_manager.h"], deps = [ ":transaction_utils", - "//chain/storage:txn_memory_db", + "//chain/state:chain_state", "//common/crypto:signature_verifier", "//interface/common:resdb_txn_accessor", "//platform/config:resdb_config", @@ -151,6 +170,7 @@ cc_library( "//platform/consensus/execution:system_info", "//platform/networkstrate:replica_communicator", "//platform/proto:viewchange_message_cc_proto", + "//platform/statistic:stats", ], ) diff --git a/platform/consensus/ordering/pbft/README.md b/platform/consensus/ordering/pbft/README.md index 84298a9bd..cf0c14238 100644 --- a/platform/consensus/ordering/pbft/README.md +++ b/platform/consensus/ordering/pbft/README.md @@ -1,3 +1,22 @@ + + # PBFT Consensus Flow Charts ## New Client Request @@ -28,4 +47,4 @@ ## Ordering Thread
-
\ No newline at end of file +
diff --git a/platform/consensus/ordering/pbft/checkpoint_manager.cpp b/platform/consensus/ordering/pbft/checkpoint_manager.cpp index cc8815633..a5a24ca82 100644 --- a/platform/consensus/ordering/pbft/checkpoint_manager.cpp +++ b/platform/consensus/ordering/pbft/checkpoint_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/checkpoint_manager.h" @@ -37,7 +31,7 @@ CheckPointManager::CheckPointManager(const ResDBConfig& config, SignatureVerifier* verifier) : config_(config), replica_communicator_(replica_communicator), - txn_db_(std::make_unique()), + txn_db_(std::make_unique()), verifier_(verifier), stop_(false), txn_accessor_(config), @@ -71,7 +65,7 @@ std::string GetHash(const std::string& h1, const std::string& h2) { return SignatureVerifier::CalculateHash(h1 + h2); } -TxnMemoryDB* CheckPointManager::GetTxnDB() { return txn_db_.get(); } +ChainState* CheckPointManager::GetTxnDB() { return txn_db_.get(); } uint64_t CheckPointManager::GetMaxTxnSeq() { return txn_db_->GetMaxSeq(); } @@ -105,7 +99,7 @@ bool CheckPointManager::IsValidCheckpointProof( senders.insert(signature.node_id()); } - return (senders.size() >= config_.GetMinDataReceiveNum()) || + return (static_cast(senders.size()) >= config_.GetMinDataReceiveNum()) || (stable_ckpt.seq() == 0 && senders.size() == 0); } @@ -171,7 +165,6 @@ bool CheckPointManager::Wait() { void CheckPointManager::UpdateStableCheckPointStatus() { uint64_t last_committable_seq = 0; - int water_mark = config_.GetCheckPointWaterMark(); while (!stop_) { if (!Wait()) { continue; @@ -319,11 +312,15 @@ void CheckPointManager::UpdateCheckPointStatus() { last_hash_ = GetHash(last_hash_, request->hash()); last_seq_++; } + bool is_recovery = request->is_recovery(); txn_db_->Put(std::move(request)); if (current_seq == last_ckpt_seq + water_mark) { last_ckpt_seq = current_seq; - BroadcastCheckPoint(last_ckpt_seq, last_hash_, stable_hashs, stable_seqs); + if (!is_recovery) { + BroadcastCheckPoint(last_ckpt_seq, last_hash_, stable_hashs, + stable_seqs); + } } } return; diff --git a/platform/consensus/ordering/pbft/checkpoint_manager.h b/platform/consensus/ordering/pbft/checkpoint_manager.h index cbde9ada5..e043978ea 100644 --- a/platform/consensus/ordering/pbft/checkpoint_manager.h +++ b/platform/consensus/ordering/pbft/checkpoint_manager.h @@ -1,33 +1,27 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once #include -#include "chain/storage/txn_memory_db.h" +#include "chain/state/chain_state.h" #include "common/crypto/signature_verifier.h" #include "interface/common/resdb_txn_accessor.h" #include "platform/config/resdb_config.h" @@ -47,7 +41,7 @@ class CheckPointManager : public CheckPoint { SignatureVerifier* verifier); virtual ~CheckPointManager(); - TxnMemoryDB* GetTxnDB(); + ChainState* GetTxnDB(); uint64_t GetMaxTxnSeq(); void AddCommitData(std::unique_ptr request); @@ -92,7 +86,7 @@ class CheckPointManager : public CheckPoint { protected: ResDBConfig config_; ReplicaCommunicator* replica_communicator_; - std::unique_ptr txn_db_; + std::unique_ptr txn_db_; std::thread checkpoint_thread_, stable_checkpoint_thread_; SignatureVerifier* verifier_; std::atomic stop_; diff --git a/platform/consensus/ordering/pbft/checkpoint_manager_test.cpp b/platform/consensus/ordering/pbft/checkpoint_manager_test.cpp index d5ef6528f..f302e8195 100644 --- a/platform/consensus/ordering/pbft/checkpoint_manager_test.cpp +++ b/platform/consensus/ordering/pbft/checkpoint_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/checkpoint_manager.h" diff --git a/platform/consensus/ordering/pbft/commitment.cpp b/platform/consensus/ordering/pbft/commitment.cpp index d30add520..4a1aacc09 100644 --- a/platform/consensus/ordering/pbft/commitment.cpp +++ b/platform/consensus/ordering/pbft/commitment.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/commitment.h" @@ -46,6 +40,12 @@ Commitment::Commitment(const ResDBConfig& config, global_stats_ = Stats::GetGlobalStats(); duplicate_manager_ = std::make_unique(config); message_manager_->SetDuplicateManager(duplicate_manager_.get()); + + global_stats_->SetProps( + config_.GetSelfInfo().id(), config_.GetSelfInfo().ip(), + config_.GetSelfInfo().port(), config_.GetConfigData().enable_resview(), + config_.GetConfigData().enable_faulty_switch()); + global_stats_->SetPrimaryId(message_manager_->GetCurrentPrimary()); } Commitment::~Commitment() { @@ -84,6 +84,8 @@ int Commitment::ProcessNewRequest(std::unique_ptr context, // << message_manager_->GetCurrentPrimary() // << " seq:" << user_request->seq() // << " hash:" << user_request->hash(); + LOG(INFO) << "NOT PRIMARY, Primary is " + << message_manager_->GetCurrentPrimary(); replica_communicator_->SendMessage(*user_request, message_manager_->GetCurrentPrimary()); { @@ -119,7 +121,6 @@ int Commitment::ProcessNewRequest(std::unique_ptr context, global_stats_->IncClientRequest(); if (duplicate_manager_->CheckAndAddProposed(user_request->hash())) { - LOG(ERROR) << "duplicate check fail:"; return -2; } auto seq = message_manager_->AssignNextSeq(); @@ -140,6 +141,8 @@ int Commitment::ProcessNewRequest(std::unique_ptr context, return -2; } + global_stats_->RecordStateTime("request"); + user_request->set_type(Request::TYPE_PRE_PREPARE); user_request->set_current_view(message_manager_->GetCurrentView()); user_request->set_seq(*seq); @@ -155,13 +158,20 @@ int Commitment::ProcessNewRequest(std::unique_ptr context, // TODO check whether the sender is the primary. int Commitment::ProcessProposeMsg(std::unique_ptr context, std::unique_ptr request) { - if (context == nullptr || context->signature.signature().empty()) { + if (global_stats_->IsFaulty() || context == nullptr || + context->signature.signature().empty()) { LOG(ERROR) << "user request doesn't contain signature, reject"; return -2; } if (request->is_recovery()) { - if (request->seq() >= message_manager_->GetNextSeq()) { + if (message_manager_->GetNextSeq() == 0 || + request->seq() == message_manager_->GetNextSeq()) { message_manager_->SetNextSeq(request->seq() + 1); + } else { + LOG(ERROR) << " recovery request not valid:" + << " current seq:" << message_manager_->GetNextSeq() + << " data seq:" << request->seq(); + return 0; } return message_manager_->AddConsensusMsg(context->signature, std::move(request)); @@ -186,6 +196,7 @@ int Commitment::ProcessProposeMsg(std::unique_ptr context, LOG(ERROR) << " check by the user func fail"; return -2; } + // global_stats_->GetTransactionDetails(std::move(request)); BatchUserRequest batch_request; batch_request.ParseFromString(request->data()); batch_request.clear_createtime(); @@ -207,6 +218,7 @@ int Commitment::ProcessProposeMsg(std::unique_ptr context, } global_stats_->IncPropose(); + global_stats_->RecordStateTime("pre-prepare"); std::unique_ptr prepare_request = resdb::NewRequest( Request::TYPE_PREPARE, *request, config_.GetSelfInfo().id()); prepare_request->clear_data(); @@ -258,6 +270,7 @@ int Commitment::ProcessPrepareMsg(std::unique_ptr context, // LOG(ERROR) << "sign hash" // << commit_request->data_signature().DebugString(); } + global_stats_->RecordStateTime("prepare"); replica_communicator_->BroadCast(*commit_request); } return ret == CollectorResultCode::INVALID ? -2 : 0; @@ -281,6 +294,11 @@ int Commitment::ProcessCommitMsg(std::unique_ptr context, // commit the request. CollectorResultCode ret = message_manager_->AddConsensusMsg(context->signature, std::move(request)); + if (ret == CollectorResultCode::STATE_CHANGED) { + // LOG(ERROR)<data().size(); + // global_stats_->GetTransactionDetails(request->data()); + global_stats_->RecordStateTime("commit"); + } return ret == CollectorResultCode::INVALID ? -2 : 0; } @@ -292,6 +310,7 @@ int Commitment::PostProcessExecutedMsg() { if (batch_resp == nullptr) { continue; } + global_stats_->SendSummary(); Request request; request.set_hash(batch_resp->hash()); request.set_seq(batch_resp->seq()); diff --git a/platform/consensus/ordering/pbft/commitment.h b/platform/consensus/ordering/pbft/commitment.h index d694caaa8..03d77cf3d 100644 --- a/platform/consensus/ordering/pbft/commitment.h +++ b/platform/consensus/ordering/pbft/commitment.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/commitment_test.cpp b/platform/consensus/ordering/pbft/commitment_test.cpp index 86e16927a..1b8b24a79 100644 --- a/platform/consensus/ordering/pbft/commitment_test.cpp +++ b/platform/consensus/ordering/pbft/commitment_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/commitment.h" diff --git a/platform/consensus/ordering/pbft/consensus_manager_pbft.cpp b/platform/consensus/ordering/pbft/consensus_manager_pbft.cpp index f1946bbe2..72103eab5 100644 --- a/platform/consensus/ordering/pbft/consensus_manager_pbft.cpp +++ b/platform/consensus/ordering/pbft/consensus_manager_pbft.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/consensus_manager_pbft.h" @@ -214,6 +208,7 @@ int ConsensusManagerPBFT::InternalConsensusCommit( int ret = commitment_->ProcessNewRequest(std::move(context), std::move(request)); if (ret == -3) { + LOG(ERROR) << "BAD RETURN"; std::pair, std::unique_ptr> request_complained; { diff --git a/platform/consensus/ordering/pbft/consensus_manager_pbft.h b/platform/consensus/ordering/pbft/consensus_manager_pbft.h index 5cefee33b..bea50990c 100644 --- a/platform/consensus/ordering/pbft/consensus_manager_pbft.h +++ b/platform/consensus/ordering/pbft/consensus_manager_pbft.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/lock_free_collector_pool.cpp b/platform/consensus/ordering/pbft/lock_free_collector_pool.cpp index 6ccc86723..4336b66d2 100644 --- a/platform/consensus/ordering/pbft/lock_free_collector_pool.cpp +++ b/platform/consensus/ordering/pbft/lock_free_collector_pool.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/lock_free_collector_pool.h" diff --git a/platform/consensus/ordering/pbft/lock_free_collector_pool.h b/platform/consensus/ordering/pbft/lock_free_collector_pool.h index 0c075e2a1..5335c4fd6 100644 --- a/platform/consensus/ordering/pbft/lock_free_collector_pool.h +++ b/platform/consensus/ordering/pbft/lock_free_collector_pool.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/lock_free_collector_pool_test.cpp b/platform/consensus/ordering/pbft/lock_free_collector_pool_test.cpp index 89e51867c..1c4d5761c 100644 --- a/platform/consensus/ordering/pbft/lock_free_collector_pool_test.cpp +++ b/platform/consensus/ordering/pbft/lock_free_collector_pool_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/lock_free_collector_pool.h" diff --git a/platform/consensus/ordering/pbft/message_manager.cpp b/platform/consensus/ordering/pbft/message_manager.cpp index b7b7bfe2a..cc5e187c6 100644 --- a/platform/consensus/ordering/pbft/message_manager.cpp +++ b/platform/consensus/ordering/pbft/message_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/message_manager.h" @@ -45,6 +39,9 @@ MessageManager::MessageManager( [&](std::unique_ptr request, std::unique_ptr resp_msg) { if (request->is_recovery()) { + if (checkpoint_manager_) { + checkpoint_manager_->AddCommitData(std::move(request)); + } return; } resp_msg->set_proxy_id(request->proxy_id()); @@ -237,8 +234,6 @@ TransactionStatue MessageManager::GetTransactionState(uint64_t seq) { } int MessageManager::GetReplicaState(ReplicaState* state) { - state->set_view(GetCurrentView()); - *state->mutable_replica_info() = config_.GetSelfInfo(); *state->mutable_replica_config() = config_.GetConfigData(); return 0; } diff --git a/platform/consensus/ordering/pbft/message_manager.h b/platform/consensus/ordering/pbft/message_manager.h index 667dfe831..c51fd22a5 100644 --- a/platform/consensus/ordering/pbft/message_manager.h +++ b/platform/consensus/ordering/pbft/message_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once @@ -32,7 +26,7 @@ #include #include -#include "chain/storage/txn_memory_db.h" +#include "chain/state/chain_state.h" #include "executor/common/transaction_manager.h" #include "platform/common/queue/lock_free_queue.h" #include "platform/config/resdb_config.h" @@ -130,7 +124,7 @@ class MessageManager { uint64_t next_seq_ = 1; LockFreeQueue queue_; - TxnMemoryDB* txn_db_; + ChainState* txn_db_; SystemInfo* system_info_; CheckPointManager* checkpoint_manager_; std::map>> diff --git a/platform/consensus/ordering/pbft/mock_checkpoint_manager.h b/platform/consensus/ordering/pbft/mock_checkpoint_manager.h index d52c22ee4..0cdd6028d 100644 --- a/platform/consensus/ordering/pbft/mock_checkpoint_manager.h +++ b/platform/consensus/ordering/pbft/mock_checkpoint_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/performance_manager.cpp b/platform/consensus/ordering/pbft/performance_manager.cpp index dfecb5940..26d0ebcaa 100644 --- a/platform/consensus/ordering/pbft/performance_manager.cpp +++ b/platform/consensus/ordering/pbft/performance_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/performance_manager.h" @@ -197,8 +191,17 @@ CollectorResultCode PerformanceManager::AddResponseMsg( return CollectorResultCode::INVALID; } + std::unique_ptr batch_response = + std::make_unique(); + if (!batch_response->ParseFromString(request->data())) { + LOG(ERROR) << "parse response fail:" << request->data().size() + << " seq:" << request->seq(); + return CollectorResultCode::INVALID; + } + + uint64_t seq = batch_response->local_id(); + int type = request->type(); - uint64_t seq = request->seq(); int resp_received_count = 0; int ret = collector_pool_->GetCollector(seq)->AddRequest( std::move(request), signature, false, diff --git a/platform/consensus/ordering/pbft/performance_manager.h b/platform/consensus/ordering/pbft/performance_manager.h index cfc6fd97b..7fc6e5967 100644 --- a/platform/consensus/ordering/pbft/performance_manager.h +++ b/platform/consensus/ordering/pbft/performance_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/pre_very_consensus_service_pbft.h b/platform/consensus/ordering/pbft/pre_very_consensus_service_pbft.h index e03852606..1b26313de 100644 --- a/platform/consensus/ordering/pbft/pre_very_consensus_service_pbft.h +++ b/platform/consensus/ordering/pbft/pre_very_consensus_service_pbft.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/query.cpp b/platform/consensus/ordering/pbft/query.cpp index f01cc2344..c2d60276b 100644 --- a/platform/consensus/ordering/pbft/query.cpp +++ b/platform/consensus/ordering/pbft/query.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/query.h" @@ -56,24 +50,65 @@ int Query::ProcessGetReplicaState(std::unique_ptr context, int Query::ProcessQuery(std::unique_ptr context, std::unique_ptr request) { + if (config_.GetPublicKeyCertificateInfo() + .public_key() + .public_key_info() + .type() == CertificateKeyInfo::CLIENT) { + auto find_primary = [&]() { + auto config_data = config_.GetConfigData(); + for (const auto& r : config_data.region()) { + for (const auto& replica : r.replica_info()) { + if (replica.id() == 1) { + return replica; + } + } + } + }; + ReplicaInfo primary = find_primary(); + std::string ip = primary.ip(); + int port = primary.port(); + + LOG(ERROR) << "redirect to primary:" << ip << " port:" << port; + auto client = std::make_unique(ip, port); + if (client->SendRawMessage(*request) == 0) { + QueryResponse resp; + if (client->RecvRawMessage(&resp) == 0) { + if (context != nullptr && context->client != nullptr) { + LOG(ERROR) << "send response from primary:" + << resp.transactions_size(); + int ret = context->client->SendRawMessage(resp); + if (ret) { + LOG(ERROR) << "send resp fail ret:" << ret; + } + } + } + } + return 0; + } + QueryRequest query; if (!query.ParseFromString(request->data())) { LOG(ERROR) << "parse data fail"; return -2; } - // LOG(ERROR) << "request:" << query.DebugString(); QueryResponse response; - for (uint64_t i = query.min_seq(); i <= query.max_seq(); ++i) { - Request* ret_request = message_manager_->GetRequest(i); - if (ret_request == nullptr) { - break; + if (query.max_seq() == 0 && query.min_seq() == 0) { + uint64_t mseq = message_manager_->GetNextSeq(); + response.set_max_seq(mseq - 1); + LOG(ERROR) << "get max seq:" << mseq; + } else { + for (uint64_t i = query.min_seq(); i <= query.max_seq(); ++i) { + Request* ret_request = message_manager_->GetRequest(i); + if (ret_request == nullptr) { + break; + } + Request* txn = response.add_transactions(); + txn->set_data(ret_request->data()); + txn->set_hash(ret_request->hash()); + txn->set_seq(ret_request->seq()); + txn->set_proxy_id(ret_request->proxy_id()); } - Request* txn = response.add_transactions(); - txn->set_data(ret_request->data()); - txn->set_hash(ret_request->hash()); - txn->set_seq(ret_request->seq()); - txn->set_proxy_id(ret_request->proxy_id()); } if (context != nullptr && context->client != nullptr) { diff --git a/platform/consensus/ordering/pbft/query.h b/platform/consensus/ordering/pbft/query.h index afc6734f6..e451cdfeb 100644 --- a/platform/consensus/ordering/pbft/query.h +++ b/platform/consensus/ordering/pbft/query.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/query_test.cpp b/platform/consensus/ordering/pbft/query_test.cpp index 54d9c6088..871dfe523 100644 --- a/platform/consensus/ordering/pbft/query_test.cpp +++ b/platform/consensus/ordering/pbft/query_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/query.h" @@ -158,10 +152,12 @@ MATCHER_P(EqualsProtoNoConfigData, replica, "") { TEST_F(QueryTest, QueryState) { ReplicaState replica_state; - replica_state.set_view(1); - replica_state.mutable_replica_info()->set_id(1); - replica_state.mutable_replica_info()->set_ip("127.0.0.1"); - replica_state.mutable_replica_info()->set_port(1234); + replica_state.mutable_replica_config()->set_view_change_timeout_ms(100); + replica_state.mutable_replica_config()->set_client_batch_num(100); + replica_state.mutable_replica_config()->set_worker_num(64); + replica_state.mutable_replica_config()->set_input_worker_num(1); + replica_state.mutable_replica_config()->set_output_worker_num(1); + replica_state.mutable_replica_config()->set_tcp_batch_num(100); std::unique_ptr channel = std::make_unique("127.0.0.1", 0); diff --git a/platform/consensus/ordering/pbft/response_manager.cpp b/platform/consensus/ordering/pbft/response_manager.cpp index 5764d96b3..f490c0039 100644 --- a/platform/consensus/ordering/pbft/response_manager.cpp +++ b/platform/consensus/ordering/pbft/response_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/response_manager.h" @@ -30,6 +24,24 @@ #include "common/utils/utils.h" namespace resdb { + +ResponseClientTimeout::ResponseClientTimeout(std::string hash_, + uint64_t time_) { + this->hash = hash_; + this->timeout_time = time_; +} + +ResponseClientTimeout::ResponseClientTimeout( + const ResponseClientTimeout& other) { + this->hash = other.hash; + this->timeout_time = other.timeout_time; +} + +bool ResponseClientTimeout::operator<( + const ResponseClientTimeout& other) const { + return timeout_time > other.timeout_time; +} + ResponseManager::ResponseManager(const ResDBConfig& config, ReplicaCommunicator* replica_communicator, SystemInfo* system_info, @@ -45,6 +57,7 @@ ResponseManager::ResponseManager(const ResDBConfig& config, verifier_(verifier) { stop_ = false; local_id_ = 1; + timeout_length_ = 5000000; if (config_.GetPublicKeyCertificateInfo() .public_key() @@ -53,6 +66,10 @@ ResponseManager::ResponseManager(const ResDBConfig& config, config_.IsTestMode()) { user_req_thread_ = std::thread(&ResponseManager::BatchProposeMsg, this); } + if (config_.GetConfigData().enable_viewchange()) { + checking_timeout_thread_ = + std::thread(&ResponseManager::MonitoringClientTimeOut, this); + } global_stats_ = Stats::GetGlobalStats(); send_num_ = 0; } @@ -62,6 +79,9 @@ ResponseManager::~ResponseManager() { if (user_req_thread_.joinable()) { user_req_thread_.join(); } + if (checking_timeout_thread_.joinable()) { + checking_timeout_thread_.join(); + } } // use system info @@ -153,8 +173,21 @@ CollectorResultCode ResponseManager::AddResponseMsg( return CollectorResultCode::INVALID; } + std::string hash = request->hash(); + + std::unique_ptr batch_response = + std::make_unique(); + if (!batch_response->ParseFromString(request->data())) { + LOG(ERROR) << "parse response fail:" << request->data().size() + << " seq:" << request->seq(); + RemoveWaitingResponseRequest(hash); + return CollectorResultCode::INVALID; + } + + uint64_t seq = batch_response->local_id(); + request->set_seq(seq); + int type = request->type(); - uint64_t seq = request->seq(); int resp_received_count = 0; int ret = collector_pool_->GetCollector(seq)->AddRequest( std::move(request), signature, false, @@ -171,6 +204,7 @@ CollectorResultCode ResponseManager::AddResponseMsg( } if (resp_received_count > 0) { collector_pool_->Update(seq); + RemoveWaitingResponseRequest(hash); return CollectorResultCode::STATE_CHANGED; } return CollectorResultCode::OK; @@ -276,7 +310,8 @@ int ResponseManager::DoBatch( if (!config_.IsPerformanceRunning()) { LOG(ERROR) << "add context list:" << new_request->seq() - << " list size:" << context_list.size(); + << " list size:" << context_list.size() + << " local_id:" << local_id_; batch_request.set_local_id(local_id_); int ret = AddContextList(std::move(context_list), local_id_++); if (ret != 0) { @@ -301,9 +336,75 @@ int ResponseManager::DoBatch( new_request->set_proxy_id(config_.GetSelfInfo().id()); replica_communicator_->SendMessage(*new_request, GetPrimary()); send_num_++; - LOG(INFO) << "send msg to primary:" << GetPrimary() - << " batch size:" << batch_req.size(); + // LOG(INFO) << "send msg to primary:" << GetPrimary() + // << " batch size:" << batch_req.size(); + AddWaitingResponseRequest(std::move(new_request)); return 0; } +void ResponseManager::AddWaitingResponseRequest( + std::unique_ptr request) { + if (!config_.GetConfigData().enable_viewchange()) { + return; + } + pm_lock_.lock(); + assert(timeout_length_ > 0); + uint64_t time = GetCurrentTime() + timeout_length_; + client_timeout_min_heap_.push(ResponseClientTimeout(request->hash(), time)); + waiting_response_batches_.insert( + make_pair(request->hash(), std::move(request))); + pm_lock_.unlock(); + sem_post(&request_sent_signal_); +} + +void ResponseManager::RemoveWaitingResponseRequest(const std::string& hash) { + if (!config_.GetConfigData().enable_viewchange()) { + return; + } + pm_lock_.lock(); + if (waiting_response_batches_.find(hash) != waiting_response_batches_.end()) { + waiting_response_batches_.erase(waiting_response_batches_.find(hash)); + } + pm_lock_.unlock(); +} + +bool ResponseManager::CheckTimeOut(std::string hash) { + pm_lock_.lock(); + bool value = + (waiting_response_batches_.find(hash) != waiting_response_batches_.end()); + pm_lock_.unlock(); + return value; +} + +std::unique_ptr ResponseManager::GetTimeOutRequest(std::string hash) { + pm_lock_.lock(); + auto value = std::move(waiting_response_batches_.find(hash)->second); + pm_lock_.unlock(); + return value; +} + +void ResponseManager::MonitoringClientTimeOut() { + while (!stop_) { + sem_wait(&request_sent_signal_); + pm_lock_.lock(); + if (client_timeout_min_heap_.empty()) { + pm_lock_.unlock(); + continue; + } + auto client_timeout = client_timeout_min_heap_.top(); + client_timeout_min_heap_.pop(); + pm_lock_.unlock(); + + if (client_timeout.timeout_time > GetCurrentTime()) { + usleep(client_timeout.timeout_time - GetCurrentTime()); + } + + if (CheckTimeOut(client_timeout.hash)) { + auto request = GetTimeOutRequest(client_timeout.hash); + if (request) { + replica_communicator_->BroadCast(*request); + } + } + } +} } // namespace resdb diff --git a/platform/consensus/ordering/pbft/response_manager.h b/platform/consensus/ordering/pbft/response_manager.h index 8b08c7fad..36412eaff 100644 --- a/platform/consensus/ordering/pbft/response_manager.h +++ b/platform/consensus/ordering/pbft/response_manager.h @@ -1,29 +1,24 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once +#include #include "platform/config/resdb_config.h" #include "platform/consensus/ordering/pbft/lock_free_collector_pool.h" @@ -33,6 +28,16 @@ namespace resdb { +class ResponseClientTimeout { + public: + ResponseClientTimeout(std::string hash_, uint64_t time_); + ResponseClientTimeout(const ResponseClientTimeout& other); + bool operator<(const ResponseClientTimeout& other) const; + + std::string hash; + uint64_t timeout_time; +}; + class ResponseManager { public: ResponseManager(const ResDBConfig& config, @@ -71,6 +76,13 @@ class ResponseManager { int BatchProposeMsg(); int GetPrimary(); + void AddWaitingResponseRequest(std::unique_ptr request); + void RemoveWaitingResponseRequest(const std::string& hash); + bool CheckTimeOut(std::string hash); + void ResponseTimer(std::string hash); + void MonitoringClientTimeOut(); + std::unique_ptr GetTimeOutRequest(std::string hash); + private: ResDBConfig config_; ReplicaCommunicator* replica_communicator_; @@ -83,6 +95,15 @@ class ResponseManager { SystemInfo* system_info_; std::atomic send_num_; SignatureVerifier* verifier_; + + std::thread checking_timeout_thread_; + std::map> waiting_response_batches_; + std::priority_queue client_timeout_min_heap_; + std::mutex pm_lock_; + uint64_t timeout_length_; + sem_t request_sent_signal_; + uint64_t highest_seq_; + uint64_t highest_seq_primary_id_; }; } // namespace resdb diff --git a/platform/consensus/ordering/pbft/response_manager_test.cpp b/platform/consensus/ordering/pbft/response_manager_test.cpp index 655b4aafe..62b16ee6f 100644 --- a/platform/consensus/ordering/pbft/response_manager_test.cpp +++ b/platform/consensus/ordering/pbft/response_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/response_manager.h" diff --git a/platform/consensus/ordering/pbft/transaction_collector.cpp b/platform/consensus/ordering/pbft/transaction_collector.cpp index 4447dfc53..0c69c401d 100644 --- a/platform/consensus/ordering/pbft/transaction_collector.cpp +++ b/platform/consensus/ordering/pbft/transaction_collector.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/transaction_collector.h" diff --git a/platform/consensus/ordering/pbft/transaction_collector.h b/platform/consensus/ordering/pbft/transaction_collector.h index 601ecbf1f..a3edaa44e 100644 --- a/platform/consensus/ordering/pbft/transaction_collector.h +++ b/platform/consensus/ordering/pbft/transaction_collector.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/transaction_collector_test.cpp b/platform/consensus/ordering/pbft/transaction_collector_test.cpp index d105082de..d1c9c7eed 100644 --- a/platform/consensus/ordering/pbft/transaction_collector_test.cpp +++ b/platform/consensus/ordering/pbft/transaction_collector_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/transaction_collector.h" diff --git a/platform/consensus/ordering/pbft/transaction_utils.cpp b/platform/consensus/ordering/pbft/transaction_utils.cpp index d5a69a3f6..5369abd02 100644 --- a/platform/consensus/ordering/pbft/transaction_utils.cpp +++ b/platform/consensus/ordering/pbft/transaction_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/transaction_utils.h" diff --git a/platform/consensus/ordering/pbft/transaction_utils.h b/platform/consensus/ordering/pbft/transaction_utils.h index fbed78396..e5e3eac22 100644 --- a/platform/consensus/ordering/pbft/transaction_utils.h +++ b/platform/consensus/ordering/pbft/transaction_utils.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/ordering/pbft/viewchange_manager.cpp b/platform/consensus/ordering/pbft/viewchange_manager.cpp index 79569baf2..3084c7a1a 100644 --- a/platform/consensus/ordering/pbft/viewchange_manager.cpp +++ b/platform/consensus/ordering/pbft/viewchange_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/viewchange_manager.h" @@ -89,6 +83,7 @@ ViewChangeManager::ViewChangeManager(const ResDBConfig& config, started_(false), stop_(false) { view_change_counter_ = 1; + global_stats_ = Stats::GetGlobalStats(); if (config_.GetConfigData().enable_viewchange()) { collector_pool_ = message_manager->GetCollectorPool(); sem_init(&viewchange_timer_signal_, 0, 0); @@ -114,6 +109,7 @@ void ViewChangeManager::MayStart() { return; } started_ = true; + LOG(ERROR) << "MAYSTART"; if (config_.GetPublicKeyCertificateInfo() .public_key() @@ -153,6 +149,7 @@ void ViewChangeManager::MayStart() { bool ViewChangeManager::ChangeStatue(ViewChangeStatus status) { if (status == ViewChangeStatus::READY_VIEW_CHANGE) { if (status_ != ViewChangeStatus::READY_VIEW_CHANGE) { + LOG(ERROR) << "CHANGE STATUS"; status_ = status; } } else { @@ -230,6 +227,8 @@ void ViewChangeManager::SetCurrentViewAndNewPrimary(uint64_t view_number) { uint32_t id = config_.GetReplicaInfos()[(view_number - 1) % replicas.size()].id(); system_info_->SetPrimary(id); + global_stats_->ChangePrimary(id); + LOG(ERROR) << "View Change Happened"; } std::vector> ViewChangeManager::GetPrepareMsg( @@ -510,6 +509,7 @@ void ViewChangeManager::SendViewChangeMsg() { } void ViewChangeManager::AddComplaintTimer(uint64_t proxy_id, std::string hash) { + LOG(ERROR) << "ADDING COMPLAINT"; std::lock_guard lk(vc_mutex_); if (complaining_clients_.count(proxy_id) == 0) { complaining_clients_[proxy_id].set_proxy_id(proxy_id); diff --git a/platform/consensus/ordering/pbft/viewchange_manager.h b/platform/consensus/ordering/pbft/viewchange_manager.h index e65eeaa18..4cc2b7cdc 100644 --- a/platform/consensus/ordering/pbft/viewchange_manager.h +++ b/platform/consensus/ordering/pbft/viewchange_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once @@ -34,6 +28,7 @@ #include "platform/consensus/ordering/pbft/message_manager.h" #include "platform/networkstrate/replica_communicator.h" #include "platform/proto/viewchange_message.pb.h" +#include "platform/statistic/stats.h" namespace resdb { @@ -134,6 +129,7 @@ class ViewChangeManager { ResDBConfig config_; CheckPointManager* checkpoint_manager_; MessageManager* message_manager_; + Stats* global_stats_; SystemInfo* system_info_; ReplicaCommunicator* replica_communicator_; SignatureVerifier* verifier_; diff --git a/platform/consensus/ordering/pbft/viewchange_manager_test.cpp b/platform/consensus/ordering/pbft/viewchange_manager_test.cpp index 83eec0013..94701535b 100644 --- a/platform/consensus/ordering/pbft/viewchange_manager_test.cpp +++ b/platform/consensus/ordering/pbft/viewchange_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/ordering/pbft/viewchange_manager.h" diff --git a/platform/consensus/ordering/poe/algorithm/BUILD b/platform/consensus/ordering/poe/algorithm/BUILD new file mode 100644 index 000000000..ece7a23f6 --- /dev/null +++ b/platform/consensus/ordering/poe/algorithm/BUILD @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +package(default_visibility = ["//platform/consensus/ordering/poe:__subpackages__"]) + +cc_library( + name = "poe", + srcs = ["poe.cpp"], + hdrs = ["poe.h"], + deps = [ + "//common:comm", + "//common/crypto:signature_verifier", + "//platform/common/queue:lock_free_queue", + "//platform/consensus/ordering/common/algorithm:protocol_base", + "//platform/consensus/ordering/poe/proto:proposal_cc_proto", + "//platform/statistic:stats", + ], +) diff --git a/platform/consensus/ordering/poe/algorithm/poe.cpp b/platform/consensus/ordering/poe/algorithm/poe.cpp new file mode 100644 index 000000000..8220d97e1 --- /dev/null +++ b/platform/consensus/ordering/poe/algorithm/poe.cpp @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "platform/consensus/ordering/poe/algorithm/poe.h" + +#include + +#include "common/crypto/signature_verifier.h" +#include "common/utils/utils.h" + +namespace resdb { +namespace poe { + +PoE::PoE(int id, int f, int total_num, SignatureVerifier* verifier) + : ProtocolBase(id, f, total_num), verifier_(verifier) { + LOG(ERROR) << "get proposal graph"; + id_ = id; + total_num_ = total_num; + f_ = f; + is_stop_ = false; + seq_ = 0; +} + +PoE::~PoE() { is_stop_ = true; } + +bool PoE::IsStop() { return is_stop_; } + +bool PoE::ReceiveTransaction(std::unique_ptr txn) { + // LOG(ERROR)<<"recv txn:"; + txn->set_create_time(GetCurrentTime()); + txn->set_seq(seq_++); + txn->set_proposer(id_); + + Broadcast(MessageType::Propose, *txn); + return true; +} + +bool PoE::ReceivePropose(std::unique_ptr txn) { + std::string hash = txn->hash(); + int64_t seq = txn->seq(); + int proposer = txn->proposer(); + { + std::unique_lock lk(mutex_); + data_[txn->hash()] = std::move(txn); + } + + Proposal proposal; + proposal.set_hash(hash); + proposal.set_seq(seq); + proposal.set_proposer(id_); + Broadcast(MessageType::Prepare, proposal); + return true; +} + +bool PoE::ReceivePrepare(std::unique_ptr proposal) { + std::unique_ptr txn = nullptr; + { + std::unique_lock lk(mutex_); + received_[proposal->hash()].insert(proposal->proposer()); + auto it = data_.find(proposal->hash()); + if (it != data_.end()) { + if (received_[proposal->hash()].size() >= 2 * f_ + 1) { + txn = std::move(it->second); + data_.erase(it); + } + } + } + if (txn != nullptr) { + commit_(*txn); + } + return true; +} + +} // namespace poe +} // namespace resdb diff --git a/platform/consensus/ordering/poe/algorithm/poe.h b/platform/consensus/ordering/poe/algorithm/poe.h new file mode 100644 index 000000000..7d1f489a3 --- /dev/null +++ b/platform/consensus/ordering/poe/algorithm/poe.h @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include +#include +#include +#include + +#include "platform/common/queue/lock_free_queue.h" +#include "platform/consensus/ordering/common/algorithm/protocol_base.h" +#include "platform/consensus/ordering/poe/proto/proposal.pb.h" +#include "platform/statistic/stats.h" + +namespace resdb { +namespace poe { + +class PoE : public common::ProtocolBase { + public: + PoE(int id, int f, int total_num, SignatureVerifier* verifier); + ~PoE(); + + bool ReceiveTransaction(std::unique_ptr txn); + bool ReceivePropose(std::unique_ptr txn); + bool ReceivePrepare(std::unique_ptr proposal); + + private: + bool IsStop(); + + private: + std::mutex mutex_; + std::map > received_; + std::map > data_; + + int64_t seq_; + bool is_stop_; + SignatureVerifier* verifier_; + Stats* global_stats_; +}; + +} // namespace poe +} // namespace resdb diff --git a/platform/consensus/ordering/poe/framework/BUILD b/platform/consensus/ordering/poe/framework/BUILD new file mode 100644 index 000000000..3d697bc4f --- /dev/null +++ b/platform/consensus/ordering/poe/framework/BUILD @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +package(default_visibility = ["//visibility:private"]) + +cc_library( + name = "consensus", + srcs = ["consensus.cpp"], + hdrs = ["consensus.h"], + visibility = [ + "//visibility:public", + ], + deps = [ + "//common/utils", + "//platform/consensus/ordering/common/framework:consensus", + "//platform/consensus/ordering/poe/algorithm:poe", + ], +) diff --git a/platform/consensus/ordering/poe/framework/consensus.cpp b/platform/consensus/ordering/poe/framework/consensus.cpp new file mode 100644 index 000000000..ef7c521e8 --- /dev/null +++ b/platform/consensus/ordering/poe/framework/consensus.cpp @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "platform/consensus/ordering/poe/framework/consensus.h" + +#include +#include + +#include "common/utils/utils.h" + +namespace resdb { +namespace poe { + +Consensus::Consensus(const ResDBConfig& config, + std::unique_ptr executor) + : common::Consensus(config, std::move(executor)) { + int total_replicas = config_.GetReplicaNum(); + int f = (total_replicas - 1) / 3; + + Init(); + + start_ = 0; + + if (config_.GetPublicKeyCertificateInfo() + .public_key() + .public_key_info() + .type() != CertificateKeyInfo::CLIENT) { + poe_ = std::make_unique(config_.GetSelfInfo().id(), f, total_replicas, + GetSignatureVerifier()); + InitProtocol(poe_.get()); + } +} + +int Consensus::ProcessCustomConsensus(std::unique_ptr request) { + if (request->user_type() == MessageType::Propose) { + std::unique_ptr txn = std::make_unique(); + if (!txn->ParseFromString(request->data())) { + assert(1 == 0); + LOG(ERROR) << "parse proposal fail"; + return -1; + } + poe_->ReceivePropose(std::move(txn)); + return 0; + } else if (request->user_type() == MessageType::Prepare) { + std::unique_ptr proposal = std::make_unique(); + if (!proposal->ParseFromString(request->data())) { + LOG(ERROR) << "parse proposal fail"; + assert(1 == 0); + return -1; + } + poe_->ReceivePrepare(std::move(proposal)); + return 0; + } + return 0; +} + +int Consensus::ProcessNewTransaction(std::unique_ptr request) { + std::unique_ptr txn = std::make_unique(); + txn->set_data(request->data()); + txn->set_hash(request->hash()); + txn->set_proxy_id(request->proxy_id()); + txn->set_uid(request->uid()); + return poe_->ReceiveTransaction(std::move(txn)); +} + +int Consensus::CommitMsg(const google::protobuf::Message& msg) { + return CommitMsgInternal(dynamic_cast(msg)); +} + +int Consensus::CommitMsgInternal(const Transaction& txn) { + std::unique_ptr request = std::make_unique(); + request->set_data(txn.data()); + request->set_seq(txn.seq()); + request->set_uid(txn.uid()); + request->set_proxy_id(txn.proxy_id()); + + transaction_executor_->Commit(std::move(request)); + return 0; +} + +} // namespace poe +} // namespace resdb diff --git a/platform/consensus/ordering/poe/framework/consensus.h b/platform/consensus/ordering/poe/framework/consensus.h new file mode 100644 index 000000000..21830d974 --- /dev/null +++ b/platform/consensus/ordering/poe/framework/consensus.h @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include "executor/common/transaction_manager.h" +#include "platform/consensus/ordering/common/framework/consensus.h" +#include "platform/consensus/ordering/poe/algorithm/poe.h" +#include "platform/networkstrate/consensus_manager.h" + +namespace resdb { +namespace poe { + +class Consensus : public common::Consensus { + public: + Consensus(const ResDBConfig& config, + std::unique_ptr transaction_manager); + virtual ~Consensus() = default; + + private: + int ProcessCustomConsensus(std::unique_ptr request) override; + int ProcessNewTransaction(std::unique_ptr request) override; + int CommitMsg(const google::protobuf::Message& msg) override; + int CommitMsgInternal(const Transaction& txn); + + int Prepare(const Transaction& txn); + + protected: + std::unique_ptr poe_; + Stats* global_stats_; + int64_t start_; + std::mutex mutex_; + int send_num_[200]; +}; + +} // namespace poe +} // namespace resdb diff --git a/platform/consensus/ordering/poe/proto/BUILD b/platform/consensus/ordering/poe/proto/BUILD new file mode 100644 index 000000000..d20d8cfe0 --- /dev/null +++ b/platform/consensus/ordering/poe/proto/BUILD @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +package(default_visibility = ["//platform/consensus/ordering/poe:__subpackages__"]) + +load("@rules_cc//cc:defs.bzl", "cc_proto_library") +load("@rules_proto//proto:defs.bzl", "proto_library") +load("@rules_proto_grpc//python:defs.bzl", "python_proto_library") + +proto_library( + name = "proposal_proto", + srcs = ["proposal.proto"], + #visibility = ["//visibility:public"], +) + +cc_proto_library( + name = "proposal_cc_proto", + deps = [":proposal_proto"], +) diff --git a/platform/consensus/ordering/poe/proto/proposal.proto b/platform/consensus/ordering/poe/proto/proposal.proto new file mode 100644 index 000000000..4f8124d45 --- /dev/null +++ b/platform/consensus/ordering/poe/proto/proposal.proto @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +syntax = "proto3"; + +package resdb.poe; + +message Transaction{ + int32 id = 1; + bytes data = 2; + bytes hash = 3; + int32 proxy_id = 4; + int32 proposer = 5; + int64 uid = 6; + int64 create_time = 7; + int64 seq = 9; +} + +message Proposal { + bytes hash = 1; + int32 proposer = 2; + int64 seq =3 ; +} + +enum MessageType { + None = 0; + Propose = 1; + Prepare = 2; +} + diff --git a/platform/consensus/recovery/BUILD b/platform/consensus/recovery/BUILD index 8426a64bf..d429c6a7e 100644 --- a/platform/consensus/recovery/BUILD +++ b/platform/consensus/recovery/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//platform/consensus:__subpackages__"]) cc_library( diff --git a/platform/consensus/recovery/recovery.cpp b/platform/consensus/recovery/recovery.cpp index b61aa4766..51faad5ce 100644 --- a/platform/consensus/recovery/recovery.cpp +++ b/platform/consensus/recovery/recovery.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/recovery/recovery.h" @@ -517,15 +511,18 @@ void Recovery::ReadLogsFromFiles( if (request_list.size() == 0) { ftruncate(fd, 0); } + uint64_t max_seq = 0; for (std::unique_ptr& recovery_data : request_list) { if (ckpt < recovery_data->request->seq()) { recovery_data->request->set_is_recovery(true); + max_seq = recovery_data->request->seq(); call_back(std::move(recovery_data->context), std::move(recovery_data->request)); } } - LOG(INFO) << "read log from files:" << path << " done"; + LOG(ERROR) << "read log from files:" << path << " done" + << " recovery max seq:" << max_seq; close(fd); } diff --git a/platform/consensus/recovery/recovery.h b/platform/consensus/recovery/recovery.h index 743846bae..90f8fc99d 100644 --- a/platform/consensus/recovery/recovery.h +++ b/platform/consensus/recovery/recovery.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/consensus/recovery/recovery_test.cpp b/platform/consensus/recovery/recovery_test.cpp index f02cb9dff..a7cb1ef86 100644 --- a/platform/consensus/recovery/recovery_test.cpp +++ b/platform/consensus/recovery/recovery_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/consensus/recovery/recovery.h" @@ -112,7 +106,7 @@ TEST_F(RecoveryTest, ReadLog) { EXPECT_EQ(list.size(), expected_types.size()); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } } @@ -153,7 +147,7 @@ TEST_F(RecoveryTest, ReadLog_FlushOnce) { EXPECT_EQ(list.size(), expected_types.size()); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } } @@ -219,7 +213,7 @@ TEST_F(RecoveryTest, CheckPoint) { EXPECT_EQ(list.size(), types.size() * 14); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } } @@ -296,7 +290,7 @@ TEST_F(RecoveryTest, CheckPoint2) { EXPECT_EQ(list.size(), types.size() * 14); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } @@ -333,7 +327,7 @@ TEST_F(RecoveryTest, CheckPoint2) { EXPECT_EQ(list.size(), types.size() * 9); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } EXPECT_EQ(recovery.GetMinSeq(), 30); @@ -415,7 +409,7 @@ TEST_F(RecoveryTest, SystemInfo) { EXPECT_EQ(list.size(), types.size() * 14); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } @@ -455,7 +449,7 @@ TEST_F(RecoveryTest, SystemInfo) { EXPECT_EQ(data.primary_id(), 2); EXPECT_EQ(list.size(), types.size() * 9); - for (int i = 0; i < expected_types.size(); ++i) { + for (size_t i = 0; i < expected_types.size(); ++i) { EXPECT_EQ(list[i].type(), expected_types[i]); } EXPECT_EQ(recovery.GetMinSeq(), 30); diff --git a/platform/networkstrate/BUILD b/platform/networkstrate/BUILD index a44b75b11..4b5107707 100644 --- a/platform/networkstrate/BUILD +++ b/platform/networkstrate/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//platform:__subpackages__"]) cc_library( diff --git a/platform/networkstrate/README.md b/platform/networkstrate/README.md index 1cf6f81cf..cc55725b4 100644 --- a/platform/networkstrate/README.md +++ b/platform/networkstrate/README.md @@ -1,3 +1,22 @@ + +
NexresRPC Server is a modern high-performance asynchronous IO Remote Procedure Call(RPC) framework that supports any service running in Byzantine Environment. diff --git a/platform/networkstrate/async_acceptor.cpp b/platform/networkstrate/async_acceptor.cpp index 0010a4a4d..b61a510b9 100644 --- a/platform/networkstrate/async_acceptor.cpp +++ b/platform/networkstrate/async_acceptor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/async_acceptor.h" @@ -83,7 +77,7 @@ void AsyncAcceptor::Session::ReadDone() { delete recv_buffer_; } else { data_size_ = *reinterpret_cast(recv_buffer_); - if (data_size_ > 1e6) { + if (data_size_ > 1e10) { LOG(ERROR) << "read data size:" << data_size_ << " data size:" << sizeof(data_size_) << " close socket"; Close(); diff --git a/platform/networkstrate/async_acceptor.h b/platform/networkstrate/async_acceptor.h index cde4893fa..26bc7ce44 100644 --- a/platform/networkstrate/async_acceptor.h +++ b/platform/networkstrate/async_acceptor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/networkstrate/async_acceptor_test.cpp b/platform/networkstrate/async_acceptor_test.cpp index 80ee4ba18..31d5ef3b0 100644 --- a/platform/networkstrate/async_acceptor_test.cpp +++ b/platform/networkstrate/async_acceptor_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/async_acceptor.h" diff --git a/platform/networkstrate/async_replica_client.cpp b/platform/networkstrate/async_replica_client.cpp index f71f86d96..af13b7996 100644 --- a/platform/networkstrate/async_replica_client.cpp +++ b/platform/networkstrate/async_replica_client.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/async_replica_client.h" diff --git a/platform/networkstrate/async_replica_client.h b/platform/networkstrate/async_replica_client.h index 2555de8fa..64189c984 100644 --- a/platform/networkstrate/async_replica_client.h +++ b/platform/networkstrate/async_replica_client.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/networkstrate/async_replica_client_test.cpp b/platform/networkstrate/async_replica_client_test.cpp index f018c0a3b..b04c1c6d0 100644 --- a/platform/networkstrate/async_replica_client_test.cpp +++ b/platform/networkstrate/async_replica_client_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/async_replica_client.h" diff --git a/platform/networkstrate/consensus_manager.cpp b/platform/networkstrate/consensus_manager.cpp index 3e1d47251..b3fb10625 100644 --- a/platform/networkstrate/consensus_manager.cpp +++ b/platform/networkstrate/consensus_manager.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/consensus_manager.h" @@ -96,46 +90,9 @@ void ConsensusManager::HeartBeat() { std::mutex mutex; std::condition_variable cv; while (IsRunning()) { - auto keys = verifier_->GetAllPublicKeys(); - - std::vector replicas = GetAllReplicas(); - LOG(ERROR) << "all replicas:" << replicas.size(); - std::vector client_replicas = GetClientReplicas(); - HeartBeatInfo hb_info; - for (const auto& key : keys) { - *hb_info.add_public_keys() = key; - } - for (const auto& client : client_replicas) { - replicas.push_back(client); - } - auto client = GetReplicaClient(replicas, false); - if (client == nullptr) { - continue; - } - - // If it is not a client node, broadcost the current primary to the client. - if (config_.GetPublicKeyCertificateInfo() - .public_key() - .public_key_info() - .type() == CertificateKeyInfo::REPLICA) { - hb_info.set_primary(GetPrimary()); - hb_info.set_version(GetVersion()); - } - LOG(ERROR) << " server:" << config_.GetSelfInfo().id() << " sends HB" - << " is ready:" << is_ready_ - << " client size:" << client_replicas.size() - << " svr size:" << replicas.size(); - - Request request; - request.set_type(Request::TYPE_HEART_BEAT); - request.mutable_region_info()->set_region_id( - config_.GetConfigData().self_region_id()); - hb_info.SerializeToString(request.mutable_data()); - - int ret = client->SendHeartBeat(request); - if (ret <= 0) { - LOG(ERROR) << " server:" << config_.GetSelfInfo().id() - << " sends HB fail:" << ret; + { + std::unique_lock lk(hb_mutex_); + SendHeartBeat(); } std::unique_lock lk(mutex); cv.wait_for(lk, std::chrono::microseconds(sleep_time * 1000000), @@ -144,12 +101,61 @@ void ConsensusManager::HeartBeat() { if (config_.IsTestMode()) { sleep_time = 1; } else { - sleep_time = 60 * 2; + sleep_time = 60; } } } } +void ConsensusManager::SendHeartBeat() { + auto keys = verifier_->GetAllPublicKeys(); + + std::vector replicas = GetAllReplicas(); + LOG(ERROR) << "all replicas:" << replicas.size(); + std::vector client_replicas = GetClientReplicas(); + HeartBeatInfo hb_info; + hb_info.set_sender(config_.GetSelfInfo().id()); + hb_info.set_ip(config_.GetSelfInfo().ip()); + hb_info.set_port(config_.GetSelfInfo().port()); + hb_info.set_hb_version(version_); + for (const auto& key : keys) { + *hb_info.add_public_keys() = key; + hb_info.add_node_version(hb_[key.public_key_info().node_id()]); + } + for (const auto& client : client_replicas) { + replicas.push_back(client); + } + auto client = GetReplicaClient(replicas, false); + if (client == nullptr) { + return; + } + + // If it is not a client node, broadcost the current primary to the client. + if (config_.GetPublicKeyCertificateInfo() + .public_key() + .public_key_info() + .type() == CertificateKeyInfo::REPLICA) { + hb_info.set_primary(GetPrimary()); + hb_info.set_version(GetVersion()); + } + LOG(ERROR) << " server:" << config_.GetSelfInfo().id() << " sends HB" + << " is ready:" << is_ready_ + << " client size:" << client_replicas.size() + << " svr size:" << replicas.size(); + + Request request; + request.set_type(Request::TYPE_HEART_BEAT); + request.mutable_region_info()->set_region_id( + config_.GetConfigData().self_region_id()); + hb_info.SerializeToString(request.mutable_data()); + + int ret = client->SendHeartBeat(request); + if (ret <= 0) { + LOG(ERROR) << " server:" << config_.GetSelfInfo().id() + << " sends HB fail:" << ret; + } +} + // Porcess the packages received from the network. // context contains the client socket which can be used for sending response to // the client, the signature for the request will be filled inside the context @@ -164,35 +170,36 @@ int ConsensusManager::Process(std::unique_ptr context, return -1; } + std::unique_ptr request = std::make_unique(); + if (!request->ParseFromString(message.data())) { + LOG(ERROR) << "parse data info fail"; + return -1; + } + + if (request->type() == Request::TYPE_HEART_BEAT) { + return Dispatch(std::move(context), std::move(request)); + } + // Check if the certificate is valid. if (message.has_signature() && verifier_) { bool valid = verifier_->VerifyMessage(message.data(), message.signature()); if (!valid) { LOG(ERROR) << "request is not valid:" << message.signature().DebugString(); - LOG(ERROR) << " msg:" << message.data().size(); + LOG(ERROR) << " msg:" << message.data().size() + << " is recovery:" << request->is_recovery(); return -2; } } else { } - std::unique_ptr request = std::make_unique(); - if (!request->ParseFromString(message.data())) { - LOG(ERROR) << "parse data info fail"; - return -1; - } - - std::string tmp; - if (!request->SerializeToString(&tmp)) { - return -1; - } - // forward the signature to the request so that it can be included in the // request/response set if needed. context->signature = message.signature(); // LOG(ERROR) << "======= server:" << config_.GetSelfInfo().id() // << " get request type:" << request->type() // << " from:" << request->sender_id(); + return Dispatch(std::move(context), std::move(request)); } @@ -208,6 +215,7 @@ int ConsensusManager::Dispatch(std::unique_ptr context, int ConsensusManager::ProcessHeartBeat(std::unique_ptr context, std::unique_ptr request) { + std::unique_lock lk(hb_mutex_); std::vector replicas = GetReplicas(); HeartBeatInfo hb_info; if (!hb_info.ParseFromString(request->data())) { @@ -215,10 +223,13 @@ int ConsensusManager::ProcessHeartBeat(std::unique_ptr context, return -1; } - LOG(INFO) << "receive public size:" << hb_info.public_keys().size() - << " primary:" << hb_info.primary() - << " version:" << hb_info.version() - << " from region:" << request->region_info().region_id(); + LOG(ERROR) << "receive public size:" << hb_info.public_keys().size() + << " primary:" << hb_info.primary() + << " version:" << hb_info.version() + << " from region:" << request->region_info().region_id() + << " sender:" << hb_info.sender() + << " last send:" << hb_info.hb_version() + << " current v:" << hb_[hb_info.sender()]; if (request->region_info().region_id() == config_.GetConfigData().self_region_id()) { @@ -267,6 +278,18 @@ int ConsensusManager::ProcessHeartBeat(std::unique_ptr context, } } } + + if (!hb_info.ip().empty() && hb_info.hb_version() > 0 && + hb_[hb_info.sender()] != hb_info.hb_version()) { + ReplicaInfo info; + info.set_ip(hb_info.ip()); + info.set_port(hb_info.port()); + info.set_id(hb_info.sender()); + // bc_client_->Flush(info); + hb_[hb_info.sender()] = hb_info.hb_version(); + SendHeartBeat(); + } + if (!is_ready_ && replica_num >= config_.GetMinDataReceiveNum()) { LOG(ERROR) << "============ Server " << config_.GetSelfInfo().id() << " is ready " diff --git a/platform/networkstrate/consensus_manager.h b/platform/networkstrate/consensus_manager.h index c87d3ac6b..57ecc836f 100644 --- a/platform/networkstrate/consensus_manager.h +++ b/platform/networkstrate/consensus_manager.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once @@ -95,6 +89,7 @@ class ConsensusManager : public ServiceInterface { private: void HeartBeat(); + void SendHeartBeat(); void BroadCastThread(); protected: @@ -111,6 +106,9 @@ class ConsensusManager : public ServiceInterface { std::unique_ptr bc_client_; std::vector clients_; Stats* global_stats_; + uint64_t version_; + std::map hb_; + std::mutex hb_mutex_; }; } // namespace resdb diff --git a/platform/networkstrate/consensus_manager_test.cpp b/platform/networkstrate/consensus_manager_test.cpp index 4b2f0b523..427b3d92e 100644 --- a/platform/networkstrate/consensus_manager_test.cpp +++ b/platform/networkstrate/consensus_manager_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/consensus_manager.h" diff --git a/platform/networkstrate/mock_async_replica_client.h b/platform/networkstrate/mock_async_replica_client.h index e31f9ccea..22f39afb3 100644 --- a/platform/networkstrate/mock_async_replica_client.h +++ b/platform/networkstrate/mock_async_replica_client.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/networkstrate/mock_replica_communicator.h b/platform/networkstrate/mock_replica_communicator.h index 79edb009e..dbcc64618 100644 --- a/platform/networkstrate/mock_replica_communicator.h +++ b/platform/networkstrate/mock_replica_communicator.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/networkstrate/mock_service_interface.h b/platform/networkstrate/mock_service_interface.h index 5d8c0f2e1..c3de6b8d0 100644 --- a/platform/networkstrate/mock_service_interface.h +++ b/platform/networkstrate/mock_service_interface.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/networkstrate/replica_communicator.cpp b/platform/networkstrate/replica_communicator.cpp index 9a07d614c..de0961252 100644 --- a/platform/networkstrate/replica_communicator.cpp +++ b/platform/networkstrate/replica_communicator.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/replica_communicator.h" @@ -263,7 +257,7 @@ void ReplicaCommunicator::SendMessage(const google::protobuf::Message& message, } if (target_replica.ip().empty()) { - LOG(ERROR) << "no replica info"; + LOG(ERROR) << "no replica info node:" << node_id; return; } diff --git a/platform/networkstrate/replica_communicator.h b/platform/networkstrate/replica_communicator.h index eb66c4fe7..24ef81012 100644 --- a/platform/networkstrate/replica_communicator.h +++ b/platform/networkstrate/replica_communicator.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/networkstrate/replica_communicator_test.cpp b/platform/networkstrate/replica_communicator_test.cpp index d21815c11..51013ff87 100644 --- a/platform/networkstrate/replica_communicator_test.cpp +++ b/platform/networkstrate/replica_communicator_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/replica_communicator.h" diff --git a/platform/networkstrate/server_comm.h b/platform/networkstrate/server_comm.h index 9fd3cd579..8eb43bfef 100644 --- a/platform/networkstrate/server_comm.h +++ b/platform/networkstrate/server_comm.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/networkstrate/service_interface.cpp b/platform/networkstrate/service_interface.cpp index 1a00676de..9379f3c47 100644 --- a/platform/networkstrate/service_interface.cpp +++ b/platform/networkstrate/service_interface.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/service_interface.h" diff --git a/platform/networkstrate/service_interface.h b/platform/networkstrate/service_interface.h index 0e3413641..4ebc84013 100644 --- a/platform/networkstrate/service_interface.h +++ b/platform/networkstrate/service_interface.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/networkstrate/service_network.cpp b/platform/networkstrate/service_network.cpp index 40cc29cea..1e69fd25b 100644 --- a/platform/networkstrate/service_network.cpp +++ b/platform/networkstrate/service_network.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/service_network.h" diff --git a/platform/networkstrate/service_network.h b/platform/networkstrate/service_network.h index d545e2694..c3844c09c 100644 --- a/platform/networkstrate/service_network.h +++ b/platform/networkstrate/service_network.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/networkstrate/service_network_test.cpp b/platform/networkstrate/service_network_test.cpp index 4b9deac1f..c92eddb57 100644 --- a/platform/networkstrate/service_network_test.cpp +++ b/platform/networkstrate/service_network_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/networkstrate/service_network.h" diff --git a/platform/proto/BUILD b/platform/proto/BUILD index 7b26b2abf..3b9166c39 100644 --- a/platform/proto/BUILD +++ b/platform/proto/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) load("@rules_cc//cc:defs.bzl", "cc_proto_library") @@ -19,7 +37,7 @@ proto_library( name = "replica_info_proto", srcs = ["replica_info.proto"], deps = [ - ":durable_proto", + "//chain/storage/proto:leveldb_config_proto", "//common/proto:signature_info_proto", ], ) @@ -34,26 +52,14 @@ cc_proto_library( python_proto_library( name = "replica_info_py_proto", protos = [ - ":durable_proto", ":replica_info_proto", + "//chain/storage/proto:leveldb_config_proto", ], deps = [ "//common/proto:signature_info_py_proto", ], ) -proto_library( - name = "durable_proto", - srcs = ["durable.proto"], -) - -cc_proto_library( - name = "durable_cc_proto", - deps = [ - ":durable_proto", - ], -) - proto_library( name = "resdb_proto", srcs = ["resdb.proto"], diff --git a/platform/proto/broadcast.proto b/platform/proto/broadcast.proto index 3f50416e4..3b2d9fbd0 100644 --- a/platform/proto/broadcast.proto +++ b/platform/proto/broadcast.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; message BroadcastData { diff --git a/platform/proto/checkpoint_info.proto b/platform/proto/checkpoint_info.proto index dec6733d4..6d4de8aef 100644 --- a/platform/proto/checkpoint_info.proto +++ b/platform/proto/checkpoint_info.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; import "common/proto/signature_info.proto"; diff --git a/platform/proto/client_test.proto b/platform/proto/client_test.proto index 08a83b4ea..be16d37e2 100644 --- a/platform/proto/client_test.proto +++ b/platform/proto/client_test.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb; diff --git a/platform/proto/durable.proto b/platform/proto/durable.proto deleted file mode 100644 index 24823a021..000000000 --- a/platform/proto/durable.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; - -package resdb; - -message RocksDBInfo { - uint32 num_threads = 2; - uint32 write_buffer_size_mb = 3; - uint32 write_batch_size = 4; - string path = 5; - bool generate_unique_pathnames = 6; -} - -message LevelDBInfo { - uint32 write_buffer_size_mb = 2; - uint32 write_batch_size = 3; - string path = 4; - bool generate_unique_pathnames = 5; -} diff --git a/platform/proto/logging.proto b/platform/proto/logging.proto index 1963b603a..4908c276a 100644 --- a/platform/proto/logging.proto +++ b/platform/proto/logging.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb; diff --git a/platform/proto/network_type.proto b/platform/proto/network_type.proto index 86ac773d4..669407045 100644 --- a/platform/proto/network_type.proto +++ b/platform/proto/network_type.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb; diff --git a/platform/proto/replica_info.proto b/platform/proto/replica_info.proto index ebfd53731..eaeac73e1 100644 --- a/platform/proto/replica_info.proto +++ b/platform/proto/replica_info.proto @@ -1,9 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb; import "common/proto/signature_info.proto"; -import "platform/proto/durable.proto"; +import "chain/storage/proto/leveldb_config.proto"; message ReplicaInfo { int64 id = 1; @@ -20,8 +39,7 @@ message RegionInfo { message ResConfigData{ repeated RegionInfo region = 1; int32 self_region_id = 2; - optional RocksDBInfo rocksdb_info = 3; - optional LevelDBInfo leveldb_info = 4; + optional storage.LevelDBInfo leveldb_info = 4; optional bool enable_viewchange = 5; optional int32 view_change_timeout_ms = 10; optional bool not_need_signature = 6; // when delivering messages, it should be signed or not. @@ -37,6 +55,8 @@ message ResConfigData{ optional string recovery_path = 18; optional int32 recovery_buffer_size = 19; optional int32 recovery_ckpt_time_s = 20; + optional bool enable_resview = 23; + optional bool enable_faulty_switch = 24; // for hotstuff. optional bool use_chain_hotstuff = 9; diff --git a/platform/proto/resdb.proto b/platform/proto/resdb.proto index b17b12404..ac60498a0 100644 --- a/platform/proto/resdb.proto +++ b/platform/proto/resdb.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; import "platform/proto/replica_info.proto"; @@ -37,8 +56,9 @@ message Request { TYPE_VIEWCHANGE = 16; TYPE_NEWVIEW= 17; TYPE_CUSTOM_QUERY = 18; + TYPE_CUSTOM_CONSENSUS = 19; - NUM_OF_TYPE = 19; // the total number of types. + NUM_OF_TYPE = 20; // the total number of types. // Used to create the collector. }; int32 type = 1; @@ -62,6 +82,12 @@ message Request { int32 primary_id = 17; repeated bytes hashs = 18; repeated uint64 seqs = 19; + int32 user_type = 20; + int64 user_seq = 21; + int64 queuing_time = 22; + int64 uid = 23; + int64 create_time = 24; + int64 commit_time = 25; } // The response message containing response @@ -108,8 +134,13 @@ message BatchUserResponse { message HeartBeatInfo{ repeated CertificateKey public_keys = 1; + repeated int64 node_version = 8; uint32 primary = 2; uint64 version= 3; + int32 sender = 4; + string ip = 5; + int32 port = 6; + int64 hb_version = 7; } message ClientCertInfo { @@ -168,6 +199,7 @@ message QueryRequest { message QueryResponse { repeated Request transactions = 1; + uint64 max_seq = 2; } message CustomQueryResponse { diff --git a/platform/proto/system_info_data.proto b/platform/proto/system_info_data.proto index a8452f6ba..9ae677881 100644 --- a/platform/proto/system_info_data.proto +++ b/platform/proto/system_info_data.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb; diff --git a/platform/proto/viewchange_message.proto b/platform/proto/viewchange_message.proto index cd0a80562..70827e0d6 100644 --- a/platform/proto/viewchange_message.proto +++ b/platform/proto/viewchange_message.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; import "platform/proto/resdb.proto"; diff --git a/platform/rdbc/BUILD b/platform/rdbc/BUILD index dce5f250b..08d9b2c08 100644 --- a/platform/rdbc/BUILD +++ b/platform/rdbc/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//platform:__subpackages__"]) cc_library( diff --git a/platform/rdbc/acceptor.cpp b/platform/rdbc/acceptor.cpp index 0e07a1c1e..0ebd832c0 100644 --- a/platform/rdbc/acceptor.cpp +++ b/platform/rdbc/acceptor.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/rdbc/acceptor.h" diff --git a/platform/rdbc/acceptor.h b/platform/rdbc/acceptor.h index 2ccc385e6..19ddb5700 100644 --- a/platform/rdbc/acceptor.h +++ b/platform/rdbc/acceptor.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/statistic/BUILD b/platform/statistic/BUILD index 4d3b5c68a..e814f9ff2 100644 --- a/platform/statistic/BUILD +++ b/platform/statistic/BUILD @@ -1,3 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = [ "//platform:__subpackages__", "//service:__subpackages__", @@ -9,8 +27,15 @@ cc_library( hdrs = ["stats.h"], deps = [ ":prometheus_handler", + "//common:asio", + "//common:beast", "//common:comm", + "//common:json", "//common/utils", + "//platform/common/network:tcp_socket", + "//platform/proto:resdb_cc_proto", + "//proto/kv:kv_cc_proto", + "//third_party:crow", "//third_party:prometheus", ], ) diff --git a/platform/statistic/README.md b/platform/statistic/README.md index b211157a3..4e666983f 100644 --- a/platform/statistic/README.md +++ b/platform/statistic/README.md @@ -1,3 +1,22 @@ + + # Introduction Nexres dynamic dashboard is a Grafana base dashboard for Nexres. It aims to provide a simple real-time interface for developers to monitor and diagnose Nexres. The data is stored in the Prometheus time-series database and queried by Grafana using PromeQL. The system usage data is provided by Prometheus third-party exporter Node Exporter. diff --git a/platform/statistic/prometheus_handler.cpp b/platform/statistic/prometheus_handler.cpp index eacadf54a..644f6a184 100644 --- a/platform/statistic/prometheus_handler.cpp +++ b/platform/statistic/prometheus_handler.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/statistic/prometheus_handler.h" diff --git a/platform/statistic/prometheus_handler.h b/platform/statistic/prometheus_handler.h index e7ceca5d7..b3a8b4d9f 100644 --- a/platform/statistic/prometheus_handler.h +++ b/platform/statistic/prometheus_handler.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/platform/statistic/set_random_data.cpp b/platform/statistic/set_random_data.cpp index a30d2cba4..0b936f585 100644 --- a/platform/statistic/set_random_data.cpp +++ b/platform/statistic/set_random_data.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/platform/statistic/stats.cpp b/platform/statistic/stats.cpp index f14ba9b3f..200ea527d 100644 --- a/platform/statistic/stats.cpp +++ b/platform/statistic/stats.cpp @@ -1,33 +1,34 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "platform/statistic/stats.h" #include +#include + #include "common/utils/utils.h" +#include "proto/kv/kv.pb.h" + +namespace asio = boost::asio; +namespace beast = boost::beast; +using tcp = asio::ip::tcp; namespace resdb { @@ -65,9 +66,22 @@ Stats::Stats(int sleep_time) { send_broad_cast_msg_ = 0; prometheus_ = nullptr; - global_thread_ = std::thread(&Stats::MonitorGlobal, this); // pass by reference + + transaction_summary_.port = -1; + + // Setup websocket here + make_faulty_.store(false); + transaction_summary_.request_pre_prepare_state_time = + std::chrono::system_clock::time_point::min(); + transaction_summary_.prepare_state_time = + std::chrono::system_clock::time_point::min(); + transaction_summary_.commit_state_time = + std::chrono::system_clock::time_point::min(); + transaction_summary_.execution_time = + std::chrono::system_clock::time_point::min(); + transaction_summary_.txn_number = 0; } void Stats::Stop() { stop_ = true; } @@ -77,6 +91,208 @@ Stats::~Stats() { if (global_thread_.joinable()) { global_thread_.join(); } + if (enable_resview && crow_thread_.joinable()) { + crow_thread_.join(); + } +} + +void Stats::CrowRoute() { + crow::SimpleApp app; + while (!stop_) { + try { + CROW_ROUTE(app, "/consensus_data") + .methods("GET"_method)([this](const crow::request& req, + crow::response& res) { + LOG(ERROR) << "API 1"; + res.set_header("Access-Control-Allow-Origin", + "*"); // Allow requests from any origin + res.set_header("Access-Control-Allow-Methods", + "GET, POST, OPTIONS"); // Specify allowed methods + res.set_header( + "Access-Control-Allow-Headers", + "Content-Type, Authorization"); // Specify allowed headers + + // Send your response + res.body = consensus_history_.dump(); + res.end(); + }); + CROW_ROUTE(app, "/get_status") + .methods("GET"_method)([this](const crow::request& req, + crow::response& res) { + LOG(ERROR) << "API 2"; + res.set_header("Access-Control-Allow-Origin", + "*"); // Allow requests from any origin + res.set_header("Access-Control-Allow-Methods", + "GET, POST, OPTIONS"); // Specify allowed methods + res.set_header( + "Access-Control-Allow-Headers", + "Content-Type, Authorization"); // Specify allowed headers + + // Send your response + res.body = IsFaulty() ? "Faulty" : "Not Faulty"; + res.end(); + }); + CROW_ROUTE(app, "/make_faulty") + .methods("GET"_method)([this](const crow::request& req, + crow::response& res) { + LOG(ERROR) << "API 3"; + res.set_header("Access-Control-Allow-Origin", + "*"); // Allow requests from any origin + res.set_header("Access-Control-Allow-Methods", + "GET, POST, OPTIONS"); // Specify allowed methods + res.set_header( + "Access-Control-Allow-Headers", + "Content-Type, Authorization"); // Specify allowed headers + + // Send your response + if (enable_faulty_switch_) { + make_faulty_.store(!make_faulty_.load()); + } + res.body = "Success"; + res.end(); + }); + app.port(8500 + transaction_summary_.port).multithreaded().run(); + sleep(1); + } catch (const std::exception& e) { + } + } + app.stop(); +} + +bool Stats::IsFaulty() { return make_faulty_.load(); } + +void Stats::ChangePrimary(int primary_id) { + transaction_summary_.primary_id = primary_id; + make_faulty_.store(false); +} + +void Stats::SetProps(int replica_id, std::string ip, int port, + bool resview_flag, bool faulty_flag) { + transaction_summary_.replica_id = replica_id; + transaction_summary_.ip = ip; + transaction_summary_.port = port; + enable_resview = resview_flag; + enable_faulty_switch_ = faulty_flag; + if (resview_flag) { + crow_thread_ = std::thread(&Stats::CrowRoute, this); + } +} + +void Stats::SetPrimaryId(int primary_id) { + transaction_summary_.primary_id = primary_id; +} + +void Stats::RecordStateTime(std::string state) { + if (!enable_resview) { + return; + } + if (state == "request" || state == "pre-prepare") { + transaction_summary_.request_pre_prepare_state_time = + std::chrono::system_clock::now(); + } else if (state == "prepare") { + transaction_summary_.prepare_state_time = std::chrono::system_clock::now(); + } else if (state == "commit") { + transaction_summary_.commit_state_time = std::chrono::system_clock::now(); + } +} + +void Stats::GetTransactionDetails(BatchUserRequest batch_request) { + if (!enable_resview) { + return; + } + transaction_summary_.txn_number = batch_request.seq(); + transaction_summary_.txn_command.clear(); + transaction_summary_.txn_key.clear(); + transaction_summary_.txn_value.clear(); + for (auto& sub_request : batch_request.user_requests()) { + KVRequest kv_request; + if (!kv_request.ParseFromString(sub_request.request().data())) { + break; + } + if (kv_request.cmd() == KVRequest::SET) { + transaction_summary_.txn_command.push_back("SET"); + transaction_summary_.txn_key.push_back(kv_request.key()); + transaction_summary_.txn_value.push_back(kv_request.value()); + } else if (kv_request.cmd() == KVRequest::GET) { + transaction_summary_.txn_command.push_back("GET"); + transaction_summary_.txn_key.push_back(kv_request.key()); + transaction_summary_.txn_value.push_back(""); + } else if (kv_request.cmd() == KVRequest::GETALLVALUES) { + transaction_summary_.txn_command.push_back("GETALLVALUES"); + transaction_summary_.txn_key.push_back(kv_request.key()); + transaction_summary_.txn_value.push_back(""); + } else if (kv_request.cmd() == KVRequest::GETRANGE) { + transaction_summary_.txn_command.push_back("GETRANGE"); + transaction_summary_.txn_key.push_back(kv_request.key()); + transaction_summary_.txn_value.push_back(kv_request.value()); + } + } +} + +void Stats::SendSummary() { + if (!enable_resview) { + return; + } + transaction_summary_.execution_time = std::chrono::system_clock::now(); + + // Convert Transaction Summary to JSON + summary_json_["replica_id"] = transaction_summary_.replica_id; + summary_json_["ip"] = transaction_summary_.ip; + summary_json_["port"] = transaction_summary_.port; + summary_json_["primary_id"] = transaction_summary_.primary_id; + summary_json_["propose_pre_prepare_time"] = + transaction_summary_.request_pre_prepare_state_time.time_since_epoch() + .count(); + summary_json_["prepare_time"] = + transaction_summary_.prepare_state_time.time_since_epoch().count(); + summary_json_["commit_time"] = + transaction_summary_.commit_state_time.time_since_epoch().count(); + summary_json_["execution_time"] = + transaction_summary_.execution_time.time_since_epoch().count(); + for (size_t i = 0; + i < transaction_summary_.prepare_message_count_times_list.size(); i++) { + summary_json_["prepare_message_timestamps"].push_back( + transaction_summary_.prepare_message_count_times_list[i] + .time_since_epoch() + .count()); + } + for (size_t i = 0; + i < transaction_summary_.commit_message_count_times_list.size(); i++) { + summary_json_["commit_message_timestamps"].push_back( + transaction_summary_.commit_message_count_times_list[i] + .time_since_epoch() + .count()); + } + summary_json_["txn_number"] = transaction_summary_.txn_number; + for (size_t i = 0; i < transaction_summary_.txn_command.size(); i++) { + summary_json_["txn_commands"].push_back( + transaction_summary_.txn_command[i]); + } + for (size_t i = 0; i < transaction_summary_.txn_key.size(); i++) { + summary_json_["txn_keys"].push_back(transaction_summary_.txn_key[i]); + } + for (size_t i = 0; i < transaction_summary_.txn_value.size(); i++) { + summary_json_["txn_values"].push_back(transaction_summary_.txn_value[i]); + } + + consensus_history_[std::to_string(transaction_summary_.txn_number)] = + summary_json_; + + LOG(ERROR) << summary_json_.dump(); + + // Reset Transaction Summary Parameters + transaction_summary_.request_pre_prepare_state_time = + std::chrono::system_clock::time_point::min(); + transaction_summary_.prepare_state_time = + std::chrono::system_clock::time_point::min(); + transaction_summary_.commit_state_time = + std::chrono::system_clock::time_point::min(); + transaction_summary_.execution_time = + std::chrono::system_clock::time_point::min(); + transaction_summary_.prepare_message_count_times_list.clear(); + transaction_summary_.commit_message_count_times_list.clear(); + + summary_json_.clear(); } void Stats::MonitorGlobal() { @@ -244,6 +460,8 @@ void Stats::IncPrepare() { prometheus_->Inc(PREPARE, 1); } num_prepare_++; + transaction_summary_.prepare_message_count_times_list.push_back( + std::chrono::system_clock::now()); } void Stats::IncCommit() { @@ -251,6 +469,8 @@ void Stats::IncCommit() { prometheus_->Inc(COMMIT, 1); } num_commit_++; + transaction_summary_.commit_message_count_times_list.push_back( + std::chrono::system_clock::now()); } void Stats::IncPendingExecute() { pending_execute_++; } diff --git a/platform/statistic/stats.h b/platform/statistic/stats.h index cc95f2bcc..0ca8dd1e2 100644 --- a/platform/statistic/stats.h +++ b/platform/statistic/stats.h @@ -1,43 +1,84 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once +#include + #include #include +#include +#include "boost/asio.hpp" +#include "boost/beast.hpp" +#include "platform/common/network/tcp_socket.h" +#include "platform/proto/resdb.pb.h" #include "platform/statistic/prometheus_handler.h" +#include "proto/kv/kv.pb.h" + +namespace asio = boost::asio; +namespace beast = boost::beast; +using tcp = asio::ip::tcp; namespace resdb { +struct VisualData { + // Set when initializing + int replica_id; + int primary_id; + std::string ip; + int port; + + // Set when new txn is received + int txn_number; + std::vector txn_command; + std::vector txn_key; + std::vector txn_value; + + // Request state if primary_id==replica_id, pre_prepare state otherwise + std::chrono::system_clock::time_point request_pre_prepare_state_time; + std::chrono::system_clock::time_point prepare_state_time; + std::vector + prepare_message_count_times_list; + std::chrono::system_clock::time_point commit_state_time; + std::vector + commit_message_count_times_list; + std::chrono::system_clock::time_point execution_time; +}; + class Stats { public: static Stats* GetGlobalStats(int sleep_seconds = 5); void Stop(); + void RetrieveProgress(); + void SetProps(int replica_id, std::string ip, int port, bool resview_flag, + bool faulty_flag); + void SetPrimaryId(int primary_id); + void RecordStateTime(std::string state); + void GetTransactionDetails(BatchUserRequest batch_request); + void SendSummary(); + void CrowRoute(); + bool IsFaulty(); + void ChangePrimary(int primary_id); + void AddLatency(uint64_t run_time); void Monitor(); @@ -98,6 +139,16 @@ class Stats { std::atomic total_request_, total_geo_request_, geo_request_; int monitor_sleep_time_ = 5; // default 5s. + std::thread crow_thread_; + bool enable_resview; + bool enable_faulty_switch_; + VisualData transaction_summary_; + std::atomic make_faulty_; + std::atomic prev_num_prepare_; + std::atomic prev_num_commit_; + nlohmann::json summary_json_; + nlohmann::json consensus_history_; + std::unique_ptr prometheus_; }; diff --git a/platform/statistic/test_server.sh b/platform/statistic/test_server.sh deleted file mode 100644 index 4ebb8bd4b..000000000 --- a/platform/statistic/test_server.sh +++ /dev/null @@ -1,8 +0,0 @@ -killall -9 kv_server - -SERVER_PATH=./bazel-bin/kv_server/kv_server -SERVER_CONFIG=example/kv_config.config -WORK_PATH=$PWD - -bazel build kv_server:kv_server -$SERVER_PATH $SERVER_CONFIG $WORK_PATH/cert/node1.key.pri $WORK_PATH/cert/cert_1.cert 127.0.0.1:8091 > server0.log & \ No newline at end of file diff --git a/platform/test/BUILD b/platform/test/BUILD index 33c9fa267..1b3282fc2 100644 --- a/platform/test/BUILD +++ b/platform/test/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:private"]) cc_test( diff --git a/platform/test/proto/BUILD b/platform/test/proto/BUILD index 0b33cd004..34ea296c1 100644 --- a/platform/test/proto/BUILD +++ b/platform/test/proto/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//platform/test:__pkg__"]) load("@rules_cc//cc:defs.bzl", "cc_proto_library") diff --git a/platform/test/proto/resdb_test.proto b/platform/test/proto/resdb_test.proto index bc09053e6..4537ddd09 100644 --- a/platform/test/proto/resdb_test.proto +++ b/platform/test/proto/resdb_test.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb; diff --git a/platform/test/resdb_test.cpp b/platform/test/resdb_test.cpp index 0152a0803..fca03a152 100644 --- a/platform/test/resdb_test.cpp +++ b/platform/test/resdb_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include @@ -109,7 +103,7 @@ class ResDBTest : public Test { void WaitExecutorDone(int received_num) { for (auto executor : executors_) { - while (executor->GetSeqs().size() < received_num) { + while (static_cast(executor->GetSeqs().size()) < received_num) { usleep(10000); } } diff --git a/platform/test/test_data/BUILD b/platform/test/test_data/BUILD index 68bd5b95a..b58db82cf 100644 --- a/platform/test/test_data/BUILD +++ b/platform/test/test_data/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//platform/test:__pkg__"]) filegroup( diff --git a/proto/contract/BUILD b/proto/contract/BUILD index 0b0943625..fb3412300 100644 --- a/proto/contract/BUILD +++ b/proto/contract/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) load("@rules_cc//cc:defs.bzl", "cc_proto_library") diff --git a/proto/contract/account.proto b/proto/contract/account.proto index e98e0364b..9dd8964f3 100644 --- a/proto/contract/account.proto +++ b/proto/contract/account.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb.contract; diff --git a/proto/contract/contract.proto b/proto/contract/contract.proto index b226ed81b..fd595dd91 100644 --- a/proto/contract/contract.proto +++ b/proto/contract/contract.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb.contract; diff --git a/proto/contract/func_params.proto b/proto/contract/func_params.proto index d1a9ca1cb..67310482f 100644 --- a/proto/contract/func_params.proto +++ b/proto/contract/func_params.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb.contract; diff --git a/proto/contract/rpc.proto b/proto/contract/rpc.proto index 1e2e49824..8939fdef6 100644 --- a/proto/contract/rpc.proto +++ b/proto/contract/rpc.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb.contract; diff --git a/proto/kv/BUILD b/proto/kv/BUILD index 8c4098b33..d65710bda 100644 --- a/proto/kv/BUILD +++ b/proto/kv/BUILD @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# package(default_visibility = ["//visibility:public"]) load("@rules_cc//cc:defs.bzl", "cc_proto_library") diff --git a/proto/kv/kv.proto b/proto/kv/kv.proto index ce0d1d260..a76c2f484 100644 --- a/proto/kv/kv.proto +++ b/proto/kv/kv.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb; @@ -7,16 +26,47 @@ message KVRequest { NONE = 0; SET = 1; GET = 2; - GETVALUES = 3; + GETALLVALUES = 3; GETRANGE = 4; + SET_WITH_VERSION = 5; + GET_WITH_VERSION = 6; + GET_ALL_ITEMS = 7; + GET_KEY_RANGE = 8; + GET_HISTORY = 9; + GET_TOP = 10; } CMD cmd = 1; string key = 2; bytes value = 3; + int32 version = 4; + // For get key range + string min_key = 5; + string max_key = 6; + // For get history for a key + int32 min_version = 7; + int32 max_version = 8; + // For top history + int32 top_number = 9; +} + +message ValueInfo { + bytes value = 2; + int32 version = 3; +} + +message Item { + string key = 1; + ValueInfo value_info = 2; +} + +message Items { + repeated Item item = 1; } message KVResponse { string key = 1; bytes value = 2; + ValueInfo value_info = 3; + Items items = 4; } diff --git a/proto/utxo/BUILD b/proto/utxo/BUILD index cf9f2823d..f9120bd52 100644 --- a/proto/utxo/BUILD +++ b/proto/utxo/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) load("@rules_cc//cc:defs.bzl", "cc_proto_library") diff --git a/proto/utxo/config.proto b/proto/utxo/config.proto index b09010215..227efcda5 100644 --- a/proto/utxo/config.proto +++ b/proto/utxo/config.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb.utxo; diff --git a/proto/utxo/rpc.proto b/proto/utxo/rpc.proto index 3713da467..add8f8728 100644 --- a/proto/utxo/rpc.proto +++ b/proto/utxo/rpc.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb.utxo; diff --git a/proto/utxo/utxo.proto b/proto/utxo/utxo.proto index 4fd417905..63137fc08 100644 --- a/proto/utxo/utxo.proto +++ b/proto/utxo/utxo.proto @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + syntax = "proto3"; package resdb.utxo; diff --git a/script.js b/script.js new file mode 100644 index 000000000..baad57a24 --- /dev/null +++ b/script.js @@ -0,0 +1,123 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +import ResilientSDK from 'https://cdn.resilientdb.com/resilient-sdk.js'; + +const sdk = new ResilientSDK(); + +// Add a message listener +sdk.addMessageListener((event) => { + const message = event.data.data; + alert(JSON.stringify(message)); // Set the message +}); + +var commit = document.querySelector('[data-nexres="commit-page-script"]'); +var fetcher = document.querySelector('[data-nexres="get-page-script"]'); +var update = document.querySelector('[data-nexres="update-page-script"]'); +var updateMulti = document.querySelector('[data-nexres="update-multi-page-script"]'); +var filter = document.querySelector('[data-nexres="filter-page-script"]'); +var account = document.querySelector('[data-nexres="account-page-script"]'); +var data = document.querySelector('[data-nexres="get-data"]'); +var amount = document.querySelector('[data-nexres="get-amount"]'); +var address = document.querySelector('[data-nexres="get-address"]'); +var id = document.querySelector('[data-nexres="get-id"]'); +var updateId = document.querySelector('[data-nexres="update-id"]'); +var updateData = document.querySelector('[data-nexres="update-data"]'); +var updateAmount = document.querySelector('[data-nexres="update-amount"]'); +var updateAddress = document.querySelector('[data-nexres="update-address"]'); +var ownerPublicKey = document.querySelector('[data-nexres="filter-owner-key"]'); +var recipientPublicKey = document.querySelector('[data-nexres="filter-recipient-key"]'); +var updateMultiId1 = document.querySelector('[data-nexres="update-multi-id1"]'); +var updateMultiData1 = document.querySelector('[data-nexres="update-multi-data1"]'); +var updateMultiAmount1 = document.querySelector('[data-nexres="update-multi-amount1"]'); +var updateMultiAddress1 = document.querySelector('[data-nexres="update-multi-address1"]'); +var updateMultiId2 = document.querySelector('[data-nexres="update-multi-id2"]'); +var updateMultiData2 = document.querySelector('[data-nexres="update-multi-data2"]'); +var updateMultiAmount2 = document.querySelector('[data-nexres="update-multi-amount2"]'); +var updateMultiAddress2 = document.querySelector('[data-nexres="update-multi-address2"]'); + +commit.addEventListener("click", commitContentScript); +fetcher.addEventListener("click", fetchContentScript); +update.addEventListener("click", updateContentScript); +updateMulti.addEventListener("click", updateMultiContentScript); +filter.addEventListener("click", filterContentScript); +account.addEventListener("click", accountContentScript); + +function commitContentScript() { + sdk.sendMessage({ + direction: "commit-page-script", + message: data.value, + amount: amount.value, + address: address.value + }); +} + +function fetchContentScript() { + sdk.sendMessage({ + direction: "get-page-script", + id: id.value + }); +} + +function updateContentScript() { + sdk.sendMessage({ + direction: "update-page-script", + id: updateId.value, + message: updateData.value, + amount: updateAmount.value, + address: updateAddress.value + }); +} + +function updateMultiContentScript() { + const valuesList = [ + { + id: updateMultiId1.value, + message: updateMultiData1.value, + amount: updateMultiAmount1.value, + address: updateMultiAddress1.value, + }, + { + id: updateMultiId2.value, + message: updateMultiData2.value, + amount: updateMultiAmount2.value, + address: updateMultiAddress2.value, + } + ]; + + sdk.sendMessage({ + direction: "update-multi-page-script", + values: valuesList + }); +} + +function filterContentScript() { + sdk.sendMessage({ + direction: "filter-page-script", + owner: ownerPublicKey.value, + recipient: recipientPublicKey.value, + }); +} + +function accountContentScript() { + sdk.sendMessage({ + direction: "account-page-script", + }); +} diff --git a/scripts/deploy/README.md b/scripts/deploy/README.md index bf8e54e31..ee41cae3a 100644 --- a/scripts/deploy/README.md +++ b/scripts/deploy/README.md @@ -1,3 +1,22 @@ + + This directory includes deployment scripts that help to deploy ResilientDB on multiple machines. At present, these scripts only support deploying KV service and KV Performance server. # Usage diff --git a/scripts/deploy/config/kv_performance_server.conf b/scripts/deploy/config/kv_performance_server.conf index 498f5a989..af36aef8f 100644 --- a/scripts/deploy/config/kv_performance_server.conf +++ b/scripts/deploy/config/kv_performance_server.conf @@ -1,8 +1,8 @@ iplist=( -172.31.23.110 -172.31.31.183 -172.31.22.246 -172.31.26.117 -172.31.21.196 +172.31.25.224 +172.31.20.228 +172.31.18.224 +172.31.16.230 +172.31.31.229 ) diff --git a/scripts/deploy/config/kv_server.conf b/scripts/deploy/config/kv_server.conf index a811f7681..500e34d6c 100644 --- a/scripts/deploy/config/kv_server.conf +++ b/scripts/deploy/config/kv_server.conf @@ -1,8 +1,8 @@ iplist=( -172.31.52.247 -172.31.54.193 -172.31.55.48 -172.31.53.140 +172.31.57.186 +172.31.57.186 +172.31.57.186 +172.31.57.186 172.31.57.186 ) diff --git a/scripts/deploy/config/poe.config b/scripts/deploy/config/poe.config new file mode 100644 index 000000000..c5092a94c --- /dev/null +++ b/scripts/deploy/config/poe.config @@ -0,0 +1,10 @@ +{ + "clientBatchNum": 100, + "enable_viewchange": false, + "recovery_enabled": false, + "max_client_complaint_num":10, + "max_process_txn": 32, + "worker_num": 2, + "input_worker_num": 1, + "output_worker_num": 10 +} diff --git a/scripts/deploy/config/template.config b/scripts/deploy/config/template.config index a68d5dc06..7962f6b04 100644 --- a/scripts/deploy/config/template.config +++ b/scripts/deploy/config/template.config @@ -1,6 +1,6 @@ { "clientBatchNum": 100, - "enable_viewchange": false, + "enable_viewchange": true, "recovery_enabled":true, "max_client_complaint_num":10 } diff --git a/scripts/deploy/performance/calculate_result.py b/scripts/deploy/performance/calculate_result.py index 5fa595980..f6892d268 100644 --- a/scripts/deploy/performance/calculate_result.py +++ b/scripts/deploy/performance/calculate_result.py @@ -1,5 +1,21 @@ -import sys +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +import sys def read_tps(file): tps = [] diff --git a/scripts/deploy/performance/pbft_performance.sh b/scripts/deploy/performance/pbft_performance.sh new file mode 100755 index 000000000..ff28bd495 --- /dev/null +++ b/scripts/deploy/performance/pbft_performance.sh @@ -0,0 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +export server=//benchmark/protocols/pbft:kv_server_performance +./performance/run_performance.sh $* diff --git a/scripts/deploy/performance/poe_performance.sh b/scripts/deploy/performance/poe_performance.sh new file mode 100755 index 000000000..37942ca0d --- /dev/null +++ b/scripts/deploy/performance/poe_performance.sh @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +export server=//benchmark/protocols/poe:kv_server_performance +export TEMPLATE_PATH=$PWD/config/poe.config + +./performance/run_performance.sh $* diff --git a/scripts/deploy/performance/run_performance.sh b/scripts/deploy/performance/run_performance.sh index 68bc9c26b..481d2e88d 100755 --- a/scripts/deploy/performance/run_performance.sh +++ b/scripts/deploy/performance/run_performance.sh @@ -1,4 +1,21 @@ -export server=//benchmark/protocols/pbft:kv_server_performance +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ./script/deploy.sh $1 diff --git a/scripts/deploy/script/deploy.sh b/scripts/deploy/script/deploy.sh index 87ab7dc92..7e03c85cc 100755 --- a/scripts/deploy/script/deploy.sh +++ b/scripts/deploy/script/deploy.sh @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + set -e # load environment parameters @@ -14,6 +33,7 @@ server=//service/kv:kv_service fi # obtain the src path +main_folder=resilientdb_app server_path=`echo "$server" | sed 's/:/\//g'` server_path=${server_path:1} server_name=`echo "$server" | awk -F':' '{print $NF}'` @@ -60,10 +80,12 @@ fi # commands functions function run_cmd(){ count=1 + idx=1 for ip in ${deploy_iplist[@]}; do - ssh -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no ubuntu@${ip} "$1" & + ssh -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no ubuntu@${ip} "cd ${main_folder}/$idx; $1" & ((count++)) + ((idx++)) done while [ $count -gt 0 ]; do @@ -76,6 +98,15 @@ function run_one_cmd(){ ssh -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no ubuntu@${ip} "$1" } +idx=1 +for ip in ${deploy_iplist[@]}; +do + run_one_cmd "mkdir -p ${main_folder}/$idx" & + ((count++)) + ((idx++)) +done + + run_cmd "killall -9 ${server_bin}" run_cmd "rm -rf ${server_bin}; rm ${server_bin}*.log; rm -rf server.config; rm -rf cert;" @@ -83,11 +114,13 @@ sleep 1 # upload config files and binary echo "upload configs" +idx=1 count=0 for ip in ${deploy_iplist[@]}; do - scp -i ${key} -r ${bin_path} ${output_path}/server.config ${output_path}/cert ubuntu@${ip}:/home/ubuntu/ & + scp -i ${key} -r ${bin_path} ${output_path}/server.config ${output_path}/cert ubuntu@${ip}:/home/ubuntu/${main_folder}/$idx & ((count++)) + ((idx++)) done while [ $count -gt 0 ]; do @@ -103,9 +136,10 @@ for ip in ${deploy_iplist[@]}; do private_key="cert/node_"${idx}".key.pri" cert="cert/cert_"${idx}".cert" - run_one_cmd "nohup ./${server_bin} server.config ${private_key} ${cert} ${grafna_port} > ${server_bin}.log 2>&1 &" & + run_one_cmd "cd ${main_folder}/$idx; nohup ./${server_bin} server.config ${private_key} ${cert} ${grafna_port} > ${server_bin}.log 2>&1 &" & ((count++)) ((idx++)) + ((grafna_port++)) done while [ $count -gt 0 ]; do @@ -120,7 +154,7 @@ do resp="" while [ "$resp" = "" ] do - resp=`ssh -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no ubuntu@${ip} "grep \"receive public size:${#iplist[@]}\" ${server_bin}.log"` + resp=`ssh -i ${key} -n -o BatchMode=yes -o StrictHostKeyChecking=no ubuntu@${ip} "cd ${main_folder}/$idx; grep \"receive public size:${#iplist[@]}\" ${server_bin}.log"` if [ "$resp" = "" ]; then sleep 1 fi diff --git a/scripts/deploy/script/env.sh b/scripts/deploy/script/env.sh index 8b03b76b5..fef33733b 100755 --- a/scripts/deploy/script/env.sh +++ b/scripts/deploy/script/env.sh @@ -1,4 +1,21 @@ - +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# set +e CURRENT_PATH=$PWD diff --git a/scripts/deploy/script/generate_config.sh b/scripts/deploy/script/generate_config.sh index c044716a3..5df2396f0 100755 --- a/scripts/deploy/script/generate_config.sh +++ b/scripts/deploy/script/generate_config.sh @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# base_path=$1; shift key_path=$1; shift output_cert_path=$1; shift diff --git a/scripts/deploy/script/generate_key.sh b/scripts/deploy/script/generate_key.sh index 4d5b08dd3..ece3e3d19 100755 --- a/scripts/deploy/script/generate_key.sh +++ b/scripts/deploy/script/generate_key.sh @@ -1,4 +1,21 @@ - +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# bazel_path=$1; shift output_path=$1; shift key_num=$1 diff --git a/scripts/deploy/script/load_config.sh b/scripts/deploy/script/load_config.sh index 85abfddda..97b2d0acf 100755 --- a/scripts/deploy/script/load_config.sh +++ b/scripts/deploy/script/load_config.sh @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# KEY_FILE="config/key.conf" . $1 diff --git a/scripts/format.sh b/scripts/format.sh index 238180272..2c255ba12 100644 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -1,2 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +bazel build @com_github_bazelbuild_buildtools//buildifier:buildifier find . ! -path "./deps/*" -type f -regex ".*\.cpp\|.*\.h" | xargs clang-format -i bazel-bin/external/com_github_bazelbuild_buildtools/buildifier/buildifier_/buildifier -r . diff --git a/service/contract/BUILD b/service/contract/BUILD index d19f5a6b1..11545b167 100644 --- a/service/contract/BUILD +++ b/service/contract/BUILD @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# package(default_visibility = ["//visibility:public"]) cc_binary( diff --git a/service/contract/contract_service.cpp b/service/contract/contract_service.cpp index 22833c27b..73826af9d 100644 --- a/service/contract/contract_service.cpp +++ b/service/contract/contract_service.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/service/kv/BUILD b/service/kv/BUILD index eed3f0be8..0e44111f3 100644 --- a/service/kv/BUILD +++ b/service/kv/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:private"]) load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") @@ -6,8 +25,7 @@ cc_binary( name = "kv_service", srcs = ["kv_service.cpp"], copts = select({ - "//executor/kv:enable_leveldb_setting": ["-DENABLE_LEVELDB"], - "//executor/kv:enable_rocksdb_setting": ["-DENABLE_ROCKSDB"], + "//chain/storage/setting:enable_leveldb_setting": ["-DENABLE_LEVELDB"], "//conditions:default": [], }), deps = [ @@ -15,11 +33,10 @@ cc_binary( "//executor/kv:kv_executor", "//service/utils:server_factory", "//common:comm", - "//chain/state:chain_state", "//proto/kv:kv_cc_proto", + "//chain/storage:memory_db", ] + select({ - "//executor/kv:enable_leveldb_setting": ["//storage:res_leveldb"], - "//executor/kv:enable_rocksdb_setting": ["//storage:res_rocksdb"], + "//chain/storage/setting:enable_leveldb_setting": ["//chain/storage:leveldb"], "//conditions:default": [], }), ) diff --git a/service/kv/kv_service.cpp b/service/kv/kv_service.cpp index 2ab9d5ff4..eda6647c7 100644 --- a/service/kv/kv_service.cpp +++ b/service/kv/kv_service.cpp @@ -1,64 +1,49 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include -#include "chain/state/chain_state.h" +#include "chain/storage/memory_db.h" #include "executor/kv/kv_executor.h" #include "platform/config/resdb_config_utils.h" #include "platform/statistic/stats.h" #include "service/utils/server_factory.h" #ifdef ENABLE_LEVELDB -#include "chain/storage/res_leveldb.h" -#endif -#ifdef ENABLE_ROCKSDB -#include "chain/storage/res_rocksdb.h" +#include "chain/storage/leveldb.h" #endif using namespace resdb; +using namespace resdb::storage; void ShowUsage() { printf(" [logging_dir]\n"); } -std::unique_ptr NewState(const std::string& cert_file, - const ResConfigData& config_data) { - std::unique_ptr storage = nullptr; - -#ifdef ENABLE_ROCKSDB - storage = NewResRocksDB(cert_file.c_str(), config_data); - LOG(INFO) << "use rocksdb storage."; -#endif - +std::unique_ptr NewStorage(const std::string& db_path, + const ResConfigData& config_data) { #ifdef ENABLE_LEVELDB - storage = NewResLevelDB(cert_file.c_str(), config_data); LOG(INFO) << "use leveldb storage."; + return NewResLevelDB(db_path, config_data); #endif - std::unique_ptr state = - std::make_unique(std::move(storage)); - return state; + + LOG(INFO) << "use memory storage."; + return NewMemoryDB(); } int main(int argc, char** argv) { @@ -66,6 +51,8 @@ int main(int argc, char** argv) { ShowUsage(); exit(0); } + google::InitGoogleLogging(argv[0]); + FLAGS_minloglevel = 1; char* config_file = argv[1]; char* private_key_file = argv[2]; @@ -84,8 +71,11 @@ int main(int argc, char** argv) { GenerateResDBConfig(config_file, private_key_file, cert_file); ResConfigData config_data = config->GetConfigData(); + std::string db_path = std::to_string(config->GetSelfInfo().port()) + "_db/"; + LOG(INFO) << "db path:" << db_path; + auto server = GenerateResDBServer( config_file, private_key_file, cert_file, - std::make_unique(NewState(cert_file, config_data)), nullptr); + std::make_unique(NewStorage(db_path, config_data)), nullptr); server->Run(); } diff --git a/service/tools/config/server/server.config b/service/tools/config/server/server.config index e75cbf7cd..b9e57d183 100644 --- a/service/tools/config/server/server.config +++ b/service/tools/config/server/server.config @@ -23,18 +23,14 @@ region_id: 1, }, self_region_id:1, - rocksdb_info : { - num_threads:1, - write_buffer_size_mb:32, - write_batch_size:1, - generate_unique_pathnames:true, - }, leveldb_info : { write_buffer_size_mb:128, write_batch_size:1, - generate_unique_pathnames:true, }, - require_txn_validation:false, + require_txn_validation:true, + enable_viewchange:false, + enable_resview:true, + enable_faulty_switch:false } diff --git a/service/tools/contract/README.md b/service/tools/contract/README.md index d3a86f1a6..54457cc2b 100644 --- a/service/tools/contract/README.md +++ b/service/tools/contract/README.md @@ -1,3 +1,22 @@ + + start the server: ./service/tools/contract/service_tools/start_contract_service.sh diff --git a/service/tools/contract/api_tools/BUILD b/service/tools/contract/api_tools/BUILD index c9c4b1d03..f0709e9ce 100644 --- a/service/tools/contract/api_tools/BUILD +++ b/service/tools/contract/api_tools/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_binary( diff --git a/service/tools/contract/api_tools/contract_tools.cpp b/service/tools/contract/api_tools/contract_tools.cpp index 430e9e5bc..0883db4ed 100644 --- a/service/tools/contract/api_tools/contract_tools.cpp +++ b/service/tools/contract/api_tools/contract_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/service/tools/contract/api_tools/example_contract/compile.sh b/service/tools/contract/api_tools/example_contract/compile.sh index e8b120c70..9692a98b2 100644 --- a/service/tools/contract/api_tools/example_contract/compile.sh +++ b/service/tools/contract/api_tools/example_contract/compile.sh @@ -1,2 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# solc --evm-version homestead --combined-json bin,hashes --pretty-json --optimize token.sol > token.json diff --git a/service/tools/contract/service_tools/start_contract_service.sh b/service/tools/contract/service_tools/start_contract_service.sh index 7eccb0234..28438d75a 100755 --- a/service/tools/contract/service_tools/start_contract_service.sh +++ b/service/tools/contract/service_tools/start_contract_service.sh @@ -1,11 +1,29 @@ -killall -9 contract_server +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +killall -9 contract_service -SERVER_PATH=./bazel-bin/service/contract/server/contract_server +SERVER_PATH=./bazel-bin/service/contract/contract_service SERVER_CONFIG=service/tools/config/server/server.config WORK_PATH=$PWD CERT_PATH=${WORK_PATH}/service/tools/data/cert/ -bazel build //service/contract/server:contract_server +bazel build //service/contract:contract_service nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node1.key.pri $CERT_PATH/cert_1.cert > server0.log & nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node2.key.pri $CERT_PATH/cert_2.cert > server1.log & nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node3.key.pri $CERT_PATH/cert_3.cert > server2.log & diff --git a/service/tools/kv/api_tools/BUILD b/service/tools/kv/api_tools/BUILD index e1f198cd9..61a7d3668 100644 --- a/service/tools/kv/api_tools/BUILD +++ b/service/tools/kv/api_tools/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_binary( diff --git a/service/tools/kv/api_tools/kv_client_txn_tools.cpp b/service/tools/kv/api_tools/kv_client_txn_tools.cpp index d73271d1e..55f0f6c49 100644 --- a/service/tools/kv/api_tools/kv_client_txn_tools.cpp +++ b/service/tools/kv/api_tools/kv_client_txn_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include @@ -55,8 +49,6 @@ int main(int argc, char** argv) { ResDBTxnAccessor client(config); auto resp = client.GetTxn(min_seq, max_seq); - absl::StatusOr>> GetTxn( - uint64_t min_seq, uint64_t max_seq); if (!resp.ok()) { LOG(ERROR) << "get replica state fail"; exit(1); diff --git a/service/tools/kv/api_tools/kv_service_tools.cpp b/service/tools/kv/api_tools/kv_service_tools.cpp index f461e42c5..b5cd53444 100644 --- a/service/tools/kv/api_tools/kv_service_tools.cpp +++ b/service/tools/kv/api_tools/kv_service_tools.cpp @@ -1,29 +1,24 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include +#include #include #include #include @@ -40,13 +35,39 @@ using resdb::KVClient; using resdb::ReplicaInfo; using resdb::ResDBConfig; -int main(int argc, char** argv) { - if (argc < 3) { - printf( - " (set/get/getvalues/getrange), [key] " - "[value/key2]\n"); - return 0; - } +void ShowUsage() { + printf( + "--config: config path\n" + "--cmd " + "set/get/set_with_version/get_with_version/get_key_range/" + "get_key_range_with_version/get_top/get_history\n" + "--key key\n" + "--value value, if cmd is a get operation\n" + "--version version of the value, if cmd is vesion based\n" + "--min_key the min key if cmd is get_key_range\n" + "--max_key the max key if cmd is get_key_range\n" + "--min_version, if cmd is get_history\n" + "--max_version, if cmd is get_history\n" + "--top, if cmd is get_top\n" + "\n" + "More examples can be found from README.\n"); +} + +static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"config", required_argument, NULL, 'c'}, + {"cmd", required_argument, NULL, 'f'}, + {"key", required_argument, NULL, 'K'}, + {"value", required_argument, NULL, 'V'}, + {"version", required_argument, NULL, 'v'}, + {"min_version", required_argument, NULL, 's'}, + {"max_version", required_argument, NULL, 'S'}, + {"min_key", required_argument, NULL, 'y'}, + {"max_key", required_argument, NULL, 'Y'}, + {"top", required_argument, NULL, 't'}, +}; + +void OldAPI(char** argv) { std::string client_config_file = argv[1]; std::string cmd = argv[2]; std::string key; @@ -80,7 +101,7 @@ int main(int argc, char** argv) { printf("client get value fail\n"); } } else if (cmd == "getvalues") { - auto res = client.GetValues(); + auto res = client.GetAllValues(); if (res != nullptr) { printf("client getvalues value = %s\n", res->c_str()); } else { @@ -95,3 +116,165 @@ int main(int argc, char** argv) { } } } + +int main(int argc, char** argv) { + std::string key; + int version = -1; + int option_index = 0; + int min_version = -1, max_version = -1; + std::string min_key, max_key; + std::string value; + std::string client_config_file; + int top = 0; + char c; + std::string cmd; + + if (argc >= 3) { + cmd = argv[2]; + if (cmd == "get" || cmd == "set" || cmd == "getvalues" || + cmd == "getrange") { + OldAPI(argv); + return 0; + } + } + + while ((c = getopt_long(argc, argv, "h", long_options, &option_index)) != + -1) { + switch (c) { + case 'c': + client_config_file = optarg; + break; + case 'f': + cmd = optarg; + break; + case 'K': + key = optarg; + break; + case 'V': + value = optarg; + break; + case 'v': + version = strtoull(optarg, NULL, 10); + break; + case 's': + min_version = strtoull(optarg, NULL, 10); + break; + case 'S': + max_version = strtoull(optarg, NULL, 10); + break; + case 'y': + min_key = optarg; + break; + case 'Y': + max_key = optarg; + break; + case 't': + top = strtoull(optarg, NULL, 10); + break; + case 'h': + ShowUsage(); + break; + } + } + + ResDBConfig config = GenerateResDBConfig(client_config_file); + + config.SetClientTimeoutMs(100000); + KVClient client(config); + if (cmd == "set_with_version") { + if (key.empty() || value.empty() || version < 0) { + ShowUsage(); + return 0; + } + int ret = client.Set(key, value, version); + printf("set key = %s, value = %s, version = %d done, ret = %d\n", + key.c_str(), value.c_str(), version, ret); + if (ret == 0) { + usleep(100000); + auto res = client.Get(key, 0); + if (res != nullptr) { + printf("current value = %s\n", res->DebugString().c_str()); + } else { + printf("get value fail\n"); + } + } + } else if (cmd == "set") { + if (key.empty() || value.empty()) { + ShowUsage(); + return 0; + } + int ret = client.Set(key, value); + printf("set key = %s, value = %s done, ret = %d\n", key.c_str(), + value.c_str(), ret); + } else if (cmd == "get_with_version") { + auto res = client.Get(key, version); + if (res != nullptr) { + printf("get key = %s, value = %s\n", key.c_str(), + res->DebugString().c_str()); + } else { + printf("get value fail\n"); + } + } else if (cmd == "get") { + auto res = client.Get(key); + if (res != nullptr) { + printf("get key = %s value = %s\n", key.c_str(), res->c_str()); + } else { + printf("get value fail\n"); + } + } else if (cmd == "get_top") { + auto res = client.GetKeyTopHistory(key, top); + if (res != nullptr) { + printf("key = %s, top %d\n value = %s\n", key.c_str(), top, + res->DebugString().c_str()); + } else { + printf("get key = %s top %d value fail\n", key.c_str(), top); + } + } else if (cmd == "get_history") { + if (key.empty() || min_version < 0 || max_version < 0 || + max_version < min_version) { + ShowUsage(); + return 0; + } + auto res = client.GetKeyHistory(key, min_version, max_version); + if (res != nullptr) { + printf( + "get history key = %s, min version = %d, max version = %d\n value = " + "%s\n", + key.c_str(), min_version, max_version, res->DebugString().c_str()); + } else { + printf( + "get history key = %s, min version = %d, max version = %d value " + "fail\n", + key.c_str(), min_version, max_version); + } + } else if (cmd == "get_key_range") { + if (min_key.empty() || max_key.empty() || min_key > max_key) { + ShowUsage(); + return 0; + } + auto res = client.GetRange(min_key, max_key); + if (res != nullptr) { + printf("getrange min key = %s, max key = %s\n value = %s\n", + min_key.c_str(), max_key.c_str(), (*res).c_str()); + } else { + printf("getrange value fail, min key = %s, max key = %s\n", + min_key.c_str(), max_key.c_str()); + } + } else if (cmd == "get_key_range_with_version") { + if (min_key.empty() || max_key.empty() || min_key > max_key) { + ShowUsage(); + return 0; + } + printf("min key = %s max key = %s\n", min_key.c_str(), max_key.c_str()); + auto res = client.GetKeyRange(min_key, max_key); + if (res != nullptr) { + printf("getrange min key = %s, max key = %s\n value = %s\n", + min_key.c_str(), max_key.c_str(), res->DebugString().c_str()); + } else { + printf("getrange value fail, min key = %s, max key = %s\n", + min_key.c_str(), max_key.c_str()); + } + } else { + ShowUsage(); + } +} diff --git a/service/tools/kv/server_tools/start_kv_service.sh b/service/tools/kv/server_tools/start_kv_service.sh index e24734356..e02731336 100755 --- a/service/tools/kv/server_tools/start_kv_service.sh +++ b/service/tools/kv/server_tools/start_kv_service.sh @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# killall -9 kv_service SERVER_PATH=./bazel-bin/service/kv/kv_service diff --git a/service/tools/kv/server_tools/start_kv_service_monitoring.sh b/service/tools/kv/server_tools/start_kv_service_monitoring.sh index 97b65863b..7f47a1b6a 100755 --- a/service/tools/kv/server_tools/start_kv_service_monitoring.sh +++ b/service/tools/kv/server_tools/start_kv_service_monitoring.sh @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# killall -9 kv_service SERVER_PATH=./bazel-bin/service/kv/kv_service diff --git a/service/tools/utxo/README.md b/service/tools/utxo/README.md index 0fc6306c6..5db5fd786 100644 --- a/service/tools/utxo/README.md +++ b/service/tools/utxo/README.md @@ -1,3 +1,21 @@ + install bech32: diff --git a/service/tools/utxo/service_tools/start_utxo_service.sh b/service/tools/utxo/service_tools/start_utxo_service.sh index c0ffc9d32..712d58825 100755 --- a/service/tools/utxo/service_tools/start_utxo_service.sh +++ b/service/tools/utxo/service_tools/start_utxo_service.sh @@ -1,4 +1,22 @@ -killall -9 utxo_server +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +killall -9 utxo_service SERVER_PATH=./bazel-bin/service/utxo/utxo_service SERVER_CONFIG=service/tools/config/server/server.config diff --git a/service/tools/utxo/wallet_tool/cpp/BUILD b/service/tools/utxo/wallet_tool/cpp/BUILD index 729dab6ee..ad7910d49 100644 --- a/service/tools/utxo/wallet_tool/cpp/BUILD +++ b/service/tools/utxo/wallet_tool/cpp/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//service/tools/utxo/wallet_tool/pybind:__subpackages__"]) cc_library( diff --git a/service/tools/utxo/wallet_tool/cpp/addr_utils.cpp b/service/tools/utxo/wallet_tool/cpp/addr_utils.cpp index 5ac9f561a..d901f9979 100644 --- a/service/tools/utxo/wallet_tool/cpp/addr_utils.cpp +++ b/service/tools/utxo/wallet_tool/cpp/addr_utils.cpp @@ -1,25 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "service/tools/utxo/wallet_tool/cpp/addr_utils.h" diff --git a/service/tools/utxo/wallet_tool/cpp/addr_utils.h b/service/tools/utxo/wallet_tool/cpp/addr_utils.h index e0904d57f..5d9fde5f4 100644 --- a/service/tools/utxo/wallet_tool/cpp/addr_utils.h +++ b/service/tools/utxo/wallet_tool/cpp/addr_utils.h @@ -1,25 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/service/tools/utxo/wallet_tool/cpp/key_utils.cpp b/service/tools/utxo/wallet_tool/cpp/key_utils.cpp index 78fd7d15f..c048a9d89 100644 --- a/service/tools/utxo/wallet_tool/cpp/key_utils.cpp +++ b/service/tools/utxo/wallet_tool/cpp/key_utils.cpp @@ -1,25 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "service/tools/utxo/wallet_tool/cpp/key_utils.h" diff --git a/service/tools/utxo/wallet_tool/cpp/key_utils.h b/service/tools/utxo/wallet_tool/cpp/key_utils.h index 783813063..134b84a0d 100644 --- a/service/tools/utxo/wallet_tool/cpp/key_utils.h +++ b/service/tools/utxo/wallet_tool/cpp/key_utils.h @@ -1,25 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/service/tools/utxo/wallet_tool/cpp/utxo_client_tools.cpp b/service/tools/utxo/wallet_tool/cpp/utxo_client_tools.cpp index 207b9233c..596b468c3 100644 --- a/service/tools/utxo/wallet_tool/cpp/utxo_client_tools.cpp +++ b/service/tools/utxo/wallet_tool/cpp/utxo_client_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include @@ -46,9 +40,11 @@ void ShowUsage() { } void Transfer(UTXOClient* client, int64_t transaction_id, - const std::string& address, const std::string& to_address, - const int value, const std::string& private_key, - const std::string& to_pub_key) { + const std::string& address, + const std::vector& to_address, + const std::vector& values, + const std::string& private_key, + const std::vector& to_pub_key) { if (private_key.empty() || to_pub_key.empty()) { printf("no private key or public key\n"); return; @@ -60,13 +56,17 @@ void Transfer(UTXOClient* client, int64_t transaction_id, in->set_out_idx(0); nonce += transaction_id; - UTXOOut* out = utxo.add_out(); - out->set_address(to_address); - out->set_value(value); - out->set_pub_key(to_pub_key); - utxo.set_address(address); - utxo.set_sig(resdb::utils::ECDSASignString(private_key, - address + std::to_string(nonce))); + for (size_t i = 0; i < to_address.size(); ++i) { + UTXOOut* out = utxo.add_out(); + out->set_address(to_address[i]); + out->set_value(values[i]); + out->set_pub_key(to_pub_key[i]); + utxo.set_address(address); + utxo.set_sig(resdb::utils::ECDSASignString( + private_key, address + std::to_string(nonce))); + LOG(ERROR) << "transfer from:" << address << " to:" << to_address[i] + << " value:" << values[i]; + } auto output = client->Transfer(utxo); LOG(ERROR) << "execute result:\n" << output; @@ -87,6 +87,34 @@ void GetWallet(UTXOClient* client, const std::string& address) { LOG(ERROR) << "address:" << address << " get wallet value:" << ret; } +std::vector ParseString(std::string str) { + std::vector ret; + while (true) { + size_t pos = str.find(","); + if (pos == std::string::npos) { + ret.push_back(str); + break; + } + ret.push_back(str.substr(0, pos)); + str = str.substr(pos + 1); + } + return ret; +} + +std::vector ParseValue(std::string str) { + std::vector ret; + while (true) { + size_t pos = str.find(","); + if (pos == std::string::npos) { + ret.push_back(strtoull(str.c_str(), NULL, 10)); + break; + } + ret.push_back(strtoull(str.substr(0, pos).c_str(), NULL, 10)); + str = str.substr(pos + 1); + } + return ret; +} + int main(int argc, char** argv) { if (argc < 3) { printf("-d -c [config]\n"); @@ -100,7 +128,7 @@ int main(int argc, char** argv) { int num = 10; int c; std::string cmd; - int64_t value = 0; + std::string value; std::string client_config_file; while ((c = getopt(argc, argv, "c:d:t:x:m:h:e:v:n:p:b:")) != -1) { switch (c) { @@ -126,7 +154,7 @@ int main(int argc, char** argv) { num = strtoull(optarg, NULL, 10); break; case 'v': - value = strtoull(optarg, NULL, 10); + value = optarg; break; case 'p': private_key = optarg; @@ -142,11 +170,10 @@ int main(int argc, char** argv) { ResDBConfig config = GenerateResDBConfig(client_config_file); config.SetClientTimeoutMs(100000); - UTXOClient client(config); if (cmd == "transfer") { - Transfer(&client, transaction_id, address, to_address, value, private_key, - to_pub_key); + Transfer(&client, transaction_id, address, ParseString(to_address), + ParseValue(value), private_key, ParseString(to_pub_key)); } else if (cmd == "list") { GetList(&client, end_id, num); } else if (cmd == "wallet") { diff --git a/service/tools/utxo/wallet_tool/py/BUILD b/service/tools/utxo/wallet_tool/py/BUILD index 0e8e8e710..205da8b39 100644 --- a/service/tools/utxo/wallet_tool/py/BUILD +++ b/service/tools/utxo/wallet_tool/py/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) py_binary( diff --git a/service/tools/utxo/wallet_tool/py/addr.py b/service/tools/utxo/wallet_tool/py/addr.py index f4cae5eb1..5b64b29f3 100644 --- a/service/tools/utxo/wallet_tool/py/addr.py +++ b/service/tools/utxo/wallet_tool/py/addr.py @@ -1,24 +1,19 @@ -# Copyright (c) 2019-2022 ExpoLab, UC Davis -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. import sys import wallet_tools_py diff --git a/service/tools/utxo/wallet_tool/py/keys.py b/service/tools/utxo/wallet_tool/py/keys.py index 72c4fdb74..c90ea9c33 100644 --- a/service/tools/utxo/wallet_tool/py/keys.py +++ b/service/tools/utxo/wallet_tool/py/keys.py @@ -1,24 +1,20 @@ -# Copyright (c) 2019-2022 ExpoLab, UC Davis -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + import wallet_tools_py diff --git a/service/tools/utxo/wallet_tool/pybind/BUILD b/service/tools/utxo/wallet_tool/pybind/BUILD index 9a6b7bad5..b42b1380a 100644 --- a/service/tools/utxo/wallet_tool/pybind/BUILD +++ b/service/tools/utxo/wallet_tool/pybind/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_binary( diff --git a/service/tools/utxo/wallet_tool/pybind/wallet_tools_py.cpp b/service/tools/utxo/wallet_tool/pybind/wallet_tools_py.cpp index c2281e794..b3f65b6bd 100644 --- a/service/tools/utxo/wallet_tool/pybind/wallet_tools_py.cpp +++ b/service/tools/utxo/wallet_tool/pybind/wallet_tools_py.cpp @@ -1,25 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/service/tools/utxo/wallet_tool/test/BUILD b/service/tools/utxo/wallet_tool/test/BUILD index 2055c2ff4..4b2d9ad24 100644 --- a/service/tools/utxo/wallet_tool/test/BUILD +++ b/service/tools/utxo/wallet_tool/test/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:private"]) cc_binary( diff --git a/service/tools/utxo/wallet_tool/test/key_tester.py b/service/tools/utxo/wallet_tool/test/key_tester.py index ca06f1409..f9112c509 100644 --- a/service/tools/utxo/wallet_tool/test/key_tester.py +++ b/service/tools/utxo/wallet_tool/test/key_tester.py @@ -1,24 +1,19 @@ -# Copyright (c) 2019-2022 ExpoLab, UC Davis -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. import wallet_tools_py import key_tester_utils diff --git a/service/tools/utxo/wallet_tool/test/key_tester_utils.cpp b/service/tools/utxo/wallet_tool/test/key_tester_utils.cpp index af7de2c80..d1744fb6c 100644 --- a/service/tools/utxo/wallet_tool/test/key_tester_utils.cpp +++ b/service/tools/utxo/wallet_tool/test/key_tester_utils.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/service/utils/BUILD b/service/utils/BUILD index a851d99a2..2849d7b43 100644 --- a/service/utils/BUILD +++ b/service/utils/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/service/utils/server_factory.cpp b/service/utils/server_factory.cpp index 61841cac9..377f03096 100644 --- a/service/utils/server_factory.cpp +++ b/service/utils/server_factory.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include "service/utils/server_factory.h" diff --git a/service/utils/server_factory.h b/service/utils/server_factory.h index 5ab7364d0..aa23254f4 100644 --- a/service/utils/server_factory.h +++ b/service/utils/server_factory.h @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #pragma once diff --git a/service/utxo/BUILD b/service/utxo/BUILD index d832e9899..a72086c66 100644 --- a/service/utxo/BUILD +++ b/service/utxo/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_binary( diff --git a/service/utxo/start_contract_server.sh b/service/utxo/start_contract_server.sh index 69914f639..01cd4a7ba 100755 --- a/service/utxo/start_contract_server.sh +++ b/service/utxo/start_contract_server.sh @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# killall -9 utxo_service SERVER_PATH=./bazel-bin/application/utxo/server/utxo_service diff --git a/service/utxo/utxo_service.cpp b/service/utxo/utxo_service.cpp index 7c5bfcc9c..c231526f1 100644 --- a/service/utxo/utxo_service.cpp +++ b/service/utxo/utxo_service.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/third_party/BUILD b/third_party/BUILD index 24eb61ae0..8d2b1b8aa 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -1,15 +1,26 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) load("@rules_foreign_cc//foreign_cc:defs.bzl", "configure_make", "make") -cc_library( - name = "rocksdb", - tags = ["manual"], - deps = [ - "@com_github_facebook_rocksdb//:rocksdb", - ], -) - cc_library( name = "prometheus", deps = [ @@ -24,12 +35,6 @@ cc_library( ], ) -make( - name = "zstd", - lib_source = "@com_facebook_zstd//:all_srcs", - out_static_libs = ["libzstd.a"], -) - cc_library( name = "leveldb", deps = [ @@ -45,3 +50,10 @@ cc_library( "@eEVM", ], ) + +cc_library( + name = "crow", + deps = [ + "@com_crowcpp_crow//:crow", + ], +) diff --git a/third_party/asio.BUILD b/third_party/asio.BUILD index 9fe1dd3ef..6f8eb603c 100644 --- a/third_party/asio.BUILD +++ b/third_party/asio.BUILD @@ -1,7 +1,27 @@ -licenses(["notice"]) +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +licenses(["notice"]) exports_files(["LICENSE"]) +package(default_visibility = ["//visibility:public"]) + cc_library( name = "asio", srcs = glob([ @@ -15,5 +35,4 @@ cc_library( "asio/**/*.ipp", ]), includes = ["asio/include"], - visibility = ["//visibility:public"], ) diff --git a/third_party/civetweb.BUILD b/third_party/civetweb.BUILD index a91b3c447..02a6de22a 100644 --- a/third_party/civetweb.BUILD +++ b/third_party/civetweb.BUILD @@ -1,3 +1,25 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +licenses(["notice"]) +exports_files(["LICENSE"]) + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/third_party/crow.BUILD b/third_party/crow.BUILD index 20cfcfcdc..3b0765a53 100644 --- a/third_party/crow.BUILD +++ b/third_party/crow.BUILD @@ -1,7 +1,27 @@ -licenses(["notice"]) +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +licenses(["notice"]) exports_files(["LICENSE"]) +package(default_visibility = ["//visibility:public"]) + cc_library( name = "crow", srcs = glob([ @@ -14,6 +34,5 @@ cc_library( ]), includes = ["include"], linkopts = ["-lpthread"], - visibility = ["//visibility:public"], deps = ["//external:asio",], ) diff --git a/third_party/date.BUILD b/third_party/date.BUILD index e7335ff4e..b5bff376c 100644 --- a/third_party/date.BUILD +++ b/third_party/date.BUILD @@ -1,11 +1,30 @@ -licenses(["notice"]) +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +licenses(["notice"]) exports_files(["LICENSE"]) +package(default_visibility = ["//visibility:public"]) + cc_library( name = "date", srcs = glob(["src/**/*.cc"]), hdrs = glob(["include/**/*.h"]), includes = ["include"], - visibility = ["//visibility:public"], -) \ No newline at end of file +) diff --git a/third_party/eEVM.BUILD b/third_party/eEVM.BUILD index 5411dfee6..684a495f7 100644 --- a/third_party/eEVM.BUILD +++ b/third_party/eEVM.BUILD @@ -1,6 +1,26 @@ -package(default_visibility = ["//visibility:public"]) +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +licenses(["notice"]) +exports_files(["LICENSE"]) -load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake") +package(default_visibility = ["//visibility:public"]) cc_library( name = "eEVM", @@ -31,6 +51,5 @@ cc_library( "3rdparty/intx/include", "3rdparty/keccak", ], - #linkstatic = 1, visibility = ["//visibility:public"], ) diff --git a/third_party/json.BUILD b/third_party/json.BUILD index 748297d4f..20cee567a 100644 --- a/third_party/json.BUILD +++ b/third_party/json.BUILD @@ -1,7 +1,26 @@ -package(default_visibility = ["//visibility:public"]) +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# -load("@rules_cc//cc:defs.bzl", "cc_library") +licenses(["notice"]) +exports_files(["LICENSE"]) +package(default_visibility = ["//visibility:public"]) cc_library( name = "json", diff --git a/third_party/leveldb.BUILD b/third_party/leveldb.BUILD index b5cb80704..cb7be9fba 100644 --- a/third_party/leveldb.BUILD +++ b/third_party/leveldb.BUILD @@ -1,3 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +licenses(["notice"]) +exports_files(["LICENSE"]) + +package(default_visibility = ["//visibility:public"]) + cc_library( name = "leveldb", srcs = glob( @@ -27,5 +51,4 @@ cc_library( ".", "include", ], - visibility = ["//visibility:public"], ) diff --git a/action.yml b/third_party/loc_script/action.yml similarity index 65% rename from action.yml rename to third_party/loc_script/action.yml index 1946350d1..5e1acd7d5 100644 --- a/action.yml +++ b/third_party/loc_script/action.yml @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + # This script is from https://github.com/shadowmoose/GHA-LoC-Badge/blob/master/action.yml name: 'lines of code Badge' diff --git a/src/index.js b/third_party/loc_script/src/index.js similarity index 98% rename from src/index.js rename to third_party/loc_script/src/index.js index 09dc4d273..29b7601d0 100644 --- a/src/index.js +++ b/third_party/loc_script/src/index.js @@ -1,4 +1,5 @@ -// This script is from https://github.com/shadowmoose/GHA-LoC-Badge/blob/master/src/index.js +// This script is from https://github.com/shadowmoose/GHA-LoC-Badge/blob/1.0.0/src/index.js +// Using the MIT license const { badgen } = require('badgen'); const fs = require('fs').promises; diff --git a/third_party/prometheus.BUILD b/third_party/prometheus.BUILD index 866f397f9..7827d7063 100644 --- a/third_party/prometheus.BUILD +++ b/third_party/prometheus.BUILD @@ -1,4 +1,26 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + licenses(["notice"]) +exports_files(["LICENSE"]) + +package(default_visibility = ["//visibility:public"]) cc_library( name = "prometheus", diff --git a/third_party/rapidjson.BUILD b/third_party/rapidjson.BUILD index 63f5aac61..d0430a5c9 100644 --- a/third_party/rapidjson.BUILD +++ b/third_party/rapidjson.BUILD @@ -1,3 +1,25 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +licenses(["notice"]) +exports_files(["LICENSE"]) + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/third_party/rocksdb.BUILD b/third_party/rocksdb.BUILD deleted file mode 100644 index d8d42096f..000000000 --- a/third_party/rocksdb.BUILD +++ /dev/null @@ -1,98 +0,0 @@ -licenses(["notice"]) - -genrule( - name = "build_version", - srcs = glob([".git/**/*"]) + [ - "util/build_version.cc.in", - ], - outs = [ - "util/build_version.cc", - ], - cmd = "grep -v 'define HAS_GIT_CHANGES' $(<) | " + - "sed 's/@ROCKSDB_PLUGIN_BUILTINS@//g' | " + - "sed 's/@ROCKSDB_PLUGIN_EXTERNS@//g' > $(@)", -) - -cc_library( - name = "rocksdb", - srcs = - glob( - [ - "**/*.h", - "**/*.cc", - "utilities/*.cc", - ], - exclude = [ - "java/**/*", - "fuzz/**", - "**/*test.cc", - "**/*bench.cc", - "microbench/**", - "third-party/**", - "util/log_write_bench.cc", - "db/forward_iterator_bench.cc", - "db/db_test2.cc", - "db_stress_tool/*.cc", - "tools/**/*.cc", - "**/**/*example.cc", - ], - ) + [":build_version"], - hdrs = glob([ - "include/rocksdb/**/*.h", - ]), - copts = [ - "-DGFLAGS=gflags", - "-DJEMALLOC_NO_DEMANGLE", - "-DOS_LINUX", - "-DSNAPPY", - "-DHAVE_SSE42", - "-DZLIB", - "-fno-omit-frame-pointer", - "-momit-leaf-frame-pointer", - "-msse4.2", - "-pthread", - "-Werror", - "-Wsign-compare", - "-Wshadow", - "-Wno-unused-parameter", - "-Wno-unused-variable", - "-Woverloaded-virtual", - "-Wnon-virtual-dtor", - "-Wno-missing-field-initializers", - "-std=c++17", - "-W", - "-Wextra", - "-Wall", - "-Wsign-compare", - "-Wno-unused-lambda-capture", - "-Wno-invalid-offsetof", - "-Wunused-variable", - "-Wshadow", - "-O3", - ], - defines = [ - "ROCKSDB_FALLOCATE_PRESENT", - "ROCKSDB_LIB_IO_POSIX", - "ROCKSDB_MALLOC_USABLE_SIZE", - "ROCKSDB_PLATFORM_POSIX", - "ROCKSDB_SUPPORT_THREAD_LOCAL", - "DISABLE_JEMALLOC", - ], - includes = [ - ".", - "include", - "util", - ], - linkopts = [ - "-lm", - "-ldl", - "-lpthread", - ], - visibility = ["//visibility:public"], - deps = [ - "//external:glog", - "//external:gtest", - "//external:snappy", - "//external:zlib", - ], -) diff --git a/third_party/snappy.BUILD b/third_party/snappy.BUILD index 56d1c394b..54d0a187d 100644 --- a/third_party/snappy.BUILD +++ b/third_party/snappy.BUILD @@ -1,6 +1,27 @@ -package(default_visibility = ["//visibility:public"]) +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + -licenses(["notice"]) # BSD 3-clause +licenses(["notice"]) +exports_files(["LICENSE"]) + +package(default_visibility = ["//visibility:public"]) filegroup( name = "license", diff --git a/third_party/z.BUILD b/third_party/z.BUILD index 34cd232c2..115995a4c 100644 --- a/third_party/z.BUILD +++ b/third_party/z.BUILD @@ -1,16 +1,34 @@ -# copied from: https://github.com/bazelbuild/bazel/blob/master/third_party/zlib/BUILD +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# -licenses(["notice"]) # BSD/MIT-like license (for zlib) +licenses(["notice"]) +exports_files(["LICENSE"]) + +package(default_visibility = ["//visibility:public"]) cc_library( name = "z", srcs = glob(["*.c"]), hdrs = glob(["*.h"]), - # Use -Dverbose=-1 to turn off zlib's trace logging. (bazelbuild/bazel#3280) copts = [ "-w", "-Dverbose=-1", ], includes = ["."], - visibility = ["//visibility:public"], ) diff --git a/third_party/zlib.BUILD b/third_party/zlib.BUILD index 7a0b0216c..c94061643 100644 --- a/third_party/zlib.BUILD +++ b/third_party/zlib.BUILD @@ -1,6 +1,26 @@ -licenses(["notice"]) # BSD/MIT-like license (for zlib) +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# -# Modified from https://github.com/tensorflow/tensorflow/blob/master/zlib.BUILD +licenses(["notice"]) +exports_files(["LICENSE"]) + +package(default_visibility = ["//visibility:public"]) cc_library( name = "zlib", @@ -37,5 +57,4 @@ cc_library( copts = [ "-D_LARGEFILE64_SOURCE=1", ], - visibility = ["//visibility:public"], ) diff --git a/third_party/zstd.BUILD b/third_party/zstd.BUILD deleted file mode 100644 index 912edd7fe..000000000 --- a/third_party/zstd.BUILD +++ /dev/null @@ -1,5 +0,0 @@ -make( - name = "zstd", - lib_source = "@com_facebook_zstd//:all_srcs", - out_static_libs = ["libzstd.a"], -) diff --git a/tools/BUILD b/tools/BUILD index 56b50b989..8d5ca0922 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + package(default_visibility = ["//visibility:public"]) cc_binary( diff --git a/tools/certificate_tools.cpp b/tools/certificate_tools.cpp index 6be804f70..92a24eae3 100644 --- a/tools/certificate_tools.cpp +++ b/tools/certificate_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/tools/certificate_tools_test.cpp b/tools/certificate_tools_test.cpp index 8748880af..42bd31652 100644 --- a/tools/certificate_tools_test.cpp +++ b/tools/certificate_tools_test.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/tools/generate_certificate.sh b/tools/generate_certificate.sh index 3957c4eb0..4f46663e2 100644 --- a/tools/generate_certificate.sh +++ b/tools/generate_certificate.sh @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# bazel build tools/certificate_tools CERT_PATH=cert/ diff --git a/tools/generate_client.sh b/tools/generate_client.sh index 5a3ea3a21..01c7ec8f4 100644 --- a/tools/generate_client.sh +++ b/tools/generate_client.sh @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ID=$1 sh $PWD/tools/generate_key.sh cert/node${ID} sh $PWD/tools/generate_certificate.sh --node_pub_key=cert/node${ID}.key.pub --node_id=$ID --save_path=cert/ diff --git a/tools/generate_cluster.sh b/tools/generate_cluster.sh index a19baf59f..0d89b15bf 100644 --- a/tools/generate_cluster.sh +++ b/tools/generate_cluster.sh @@ -1,4 +1,21 @@ - +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# sh $PWD/tools/generate_key.sh cert/node1 sh $PWD/tools/generate_certificate.sh --node_pub_key=cert/node1.key.pub --node_id=1 --ip=127.0.0.1 --port=10001 --save_path=cert/ diff --git a/tools/generate_key.sh b/tools/generate_key.sh index f95ebb9ca..7b800df3e 100644 --- a/tools/generate_key.sh +++ b/tools/generate_key.sh @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# bazel build tools/key_generator_tools path=$1 bazel-bin/tools/key_generator_tools $path diff --git a/tools/generate_mulregion_config.py b/tools/generate_mulregion_config.py index 424a343cc..e25642f87 100644 --- a/tools/generate_mulregion_config.py +++ b/tools/generate_mulregion_config.py @@ -1,3 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + import os import json import sys diff --git a/tools/generate_region_config.py b/tools/generate_region_config.py index 3dd46f816..c3d001f22 100644 --- a/tools/generate_region_config.py +++ b/tools/generate_region_config.py @@ -1,3 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + import os import json import sys diff --git a/tools/key_generator_tools.cpp b/tools/key_generator_tools.cpp index 80c063324..93b15d9cd 100644 --- a/tools/key_generator_tools.cpp +++ b/tools/key_generator_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include diff --git a/tools/resdb_state_accessor_tools.cpp b/tools/resdb_state_accessor_tools.cpp index 8aaa45d4c..618278380 100644 --- a/tools/resdb_state_accessor_tools.cpp +++ b/tools/resdb_state_accessor_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include @@ -40,12 +34,10 @@ int main(int argc, char** argv) { ResDBConfig config = GenerateResDBConfig(config_file); ResDBStateAccessor client(config); - auto states = client.GetReplicaStates(); + auto states = client.GetReplicaState(); if (!states.ok()) { LOG(ERROR) << "get replica state fail"; exit(1); } - for (auto& state : *states) { - LOG(ERROR) << state.DebugString(); - } + LOG(ERROR) << (*states).DebugString(); } diff --git a/tools/resdb_txn_accessor_tools.cpp b/tools/resdb_txn_accessor_tools.cpp index 35cc37c0d..38cb2a408 100644 --- a/tools/resdb_txn_accessor_tools.cpp +++ b/tools/resdb_txn_accessor_tools.cpp @@ -1,26 +1,20 @@ /* - * Copyright (c) 2019-2022 ExpoLab, UC Davis + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #include