Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f975e9ed37 |
@@ -7,10 +7,13 @@ RUN apt-get update && apt-get upgrade -y && \
|
||||
g++-8 \
|
||||
git \
|
||||
jq \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0-dev \
|
||||
llvm-7-dev \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
python3 \
|
||||
software-properties-common \
|
||||
zlib1g-dev \
|
||||
|
||||
@@ -7,8 +7,11 @@ RUN apt-get update && apt-get upgrade -y && \
|
||||
git \
|
||||
jq \
|
||||
libboost-all-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0-dev \
|
||||
llvm-11-dev \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
zstd
|
||||
|
||||
@@ -7,8 +7,11 @@ RUN apt-get update && apt-get upgrade -y && \
|
||||
git \
|
||||
jq \
|
||||
libboost-all-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0-dev \
|
||||
llvm-11-dev \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
zstd
|
||||
|
||||
@@ -12,7 +12,6 @@ jobs:
|
||||
label: triage
|
||||
org-project: 'Team Backlog'
|
||||
project-field: Status=Todo
|
||||
skip-if-existing-project: true
|
||||
secrets:
|
||||
token: ${{secrets.ENFCIBOT_REPO_AND_PROJECTS}}
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
[submodule "libraries/rapidjson"]
|
||||
path = libraries/rapidjson
|
||||
url = https://github.com/Tencent/rapidjson/
|
||||
[submodule "libraries/yubihsm"]
|
||||
path = libraries/yubihsm
|
||||
url = https://github.com/Yubico/yubihsm-shell
|
||||
[submodule "tests/abieos"]
|
||||
path = tests/abieos
|
||||
url = https://github.com/AntelopeIO/abieos
|
||||
|
||||
+9
-3
@@ -13,10 +13,10 @@ set( CMAKE_CXX_STANDARD 17 )
|
||||
set( CMAKE_CXX_EXTENSIONS ON )
|
||||
set( CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(VERSION_MAJOR 4)
|
||||
set(VERSION_MINOR 0)
|
||||
set(VERSION_MAJOR 3)
|
||||
set(VERSION_MINOR 2)
|
||||
set(VERSION_PATCH 0)
|
||||
set(VERSION_SUFFIX dev)
|
||||
set(VERSION_SUFFIX rc1)
|
||||
|
||||
if(VERSION_SUFFIX)
|
||||
set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}")
|
||||
@@ -60,6 +60,8 @@ if(APPLE AND UNIX AND "${OPENSSL_ROOT_DIR}" STREQUAL "")
|
||||
set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl@3;/usr/local/opt/openssl@1.1")
|
||||
endif()
|
||||
endif()
|
||||
# fc also adds these definitions to its public interface. once fc becomes the sole importer of openssl, this should be removed
|
||||
add_definitions(-DOPENSSL_API_COMPAT=0x10100000L -DOPENSSL_NO_DEPRECATED)
|
||||
|
||||
option(ENABLE_OC "Enable eosvm-oc on supported platforms" ON)
|
||||
|
||||
@@ -222,6 +224,7 @@ configure_file(libraries/libfc/src/network/LICENSE.go licen
|
||||
configure_file(libraries/eos-vm/LICENSE licenses/leap/LICENSE.eos-vm COPYONLY)
|
||||
configure_file(libraries/libfc/libraries/ff/LICENSE licenses/leap/LICENSE.libff COPYONLY)
|
||||
configure_file(programs/cleos/LICENSE.CLI11 licenses/leap/LICENSE.CLI11 COPYONLY)
|
||||
configure_file(libraries/yubihsm/LICENSE licenses/leap/LICENSE.yubihsm COPYONLY)
|
||||
|
||||
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/licenses/leap" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/" COMPONENT base)
|
||||
|
||||
@@ -240,6 +243,9 @@ add_custom_target(dev-install
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
get_property(_CTEST_CUSTOM_TESTS_IGNORE GLOBAL PROPERTY CTEST_CUSTOM_TESTS_IGNORE)
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/CTestCustom.cmake" "SET(CTEST_CUSTOM_TESTS_IGNORE ${_CTEST_CUSTOM_TESTS_IGNORE})")
|
||||
|
||||
include(doxygen)
|
||||
|
||||
include(package.cmake)
|
||||
|
||||
@@ -51,7 +51,7 @@ find_package(Boost @Boost_MAJOR_VERSION@.@Boost_MINOR_VERSION@ EXACT REQUIRED CO
|
||||
|
||||
find_library(libtester eosio_testing @CMAKE_BINARY_DIR@/libraries/testing NO_DEFAULT_PATH)
|
||||
find_library(libchain eosio_chain @CMAKE_BINARY_DIR@/libraries/chain NO_DEFAULT_PATH)
|
||||
find_library(libfc fc @CMAKE_BINARY_DIR@/libraries/libfc NO_DEFAULT_PATH)
|
||||
find_library(libfc fc @CMAKE_BINARY_DIR@/libraries/fc NO_DEFAULT_PATH)
|
||||
find_library(libsecp256k1 secp256k1 @CMAKE_BINARY_DIR@/libraries/libfc/secp256k1 NO_DEFAULT_PATH)
|
||||
|
||||
find_library(libff ff @CMAKE_BINARY_DIR@/libraries/libfc/libraries/ff/libff NO_DEFAULT_PATH)
|
||||
|
||||
@@ -50,7 +50,9 @@ Requirements to build:
|
||||
- LLVM 7 - 11 - for Linux only
|
||||
- newer versions do not work
|
||||
- openssl 1.1+
|
||||
- libcurl
|
||||
- curl
|
||||
- libusb
|
||||
- git
|
||||
- GMP
|
||||
- Python 3
|
||||
@@ -134,16 +136,19 @@ sudo apt-get install -y \
|
||||
curl \
|
||||
git \
|
||||
libboost-all-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
llvm-11-dev
|
||||
libusb-1.0-0-dev \
|
||||
llvm-11-dev \
|
||||
pkg-config
|
||||
```
|
||||
To build, make sure you are in the root of the `leap` repo, then run the following command:
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/usr/lib/llvm-11 ..
|
||||
make -j "$(nproc)" package
|
||||
make -j $(nproc) package
|
||||
```
|
||||
</details>
|
||||
|
||||
@@ -158,9 +163,12 @@ sudo apt-get install -y \
|
||||
curl \
|
||||
g++-8 \
|
||||
git \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0-dev \
|
||||
llvm-7-dev \
|
||||
pkg-config \
|
||||
python3 \
|
||||
zlib1g-dev
|
||||
```
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
content_title: Build Antelope from Source
|
||||
---
|
||||
|
||||
The shell scripts previously recommended for building the software have been removed in favor of a build process entirely driven by CMake. Those wishing to build from source are now responsible for installing the necessary dependencies. The list of dependencies and the recommended build procedure are in the [`README.md`](https://github.com/AntelopeIO/leap/blob/main/README.md) file. Instructions are also included for efficiently running the tests.
|
||||
The shell scripts previously recommended for building the software have been removed in favor of a build process entirely driven by CMake. Those wishing to build from source are now responsible for installing the necessary dependencies. The list of dependencies and the recommended build procedure are in the [`README.md`](https://github.com/AntelopeIO/leap/blob/release/3.2/README.md) file. Instructions are also included for efficiently running the tests.
|
||||
|
||||
### Using DUNE
|
||||
As an alternative to building from source, try [Docker Utilities for Node Execution](https://github.com/AntelopeIO/DUNE) for the easiest way to get started and for multi-platform support.
|
||||
|
||||
### Building From Source
|
||||
You can also build and install Leap from source. Instructions for that currently live [here](https://github.com/AntelopeIO/leap/blob/main/README.md#build-and-install-from-source).
|
||||
You can also build and install Leap from source. Instructions for that currently live [here](https://github.com/AntelopeIO/leap/blob/release/3.2/README.md#build-and-install-from-source).
|
||||
|
||||
#### Building Pinned Build Binary Packages
|
||||
The pinned build instructions have moved [here](https://github.com/AntelopeIO/leap/blob/main/README.md#pinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/main/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/main/README.md#step-3---build) before you build.
|
||||
The pinned build instructions have moved [here](https://github.com/AntelopeIO/leap/blob/release/3.2/README.md#pinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/release/3.2/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/release/3.2/README.md#step-3---build) before you build.
|
||||
|
||||
#### Manual (non "pinned") Build Instructions
|
||||
The unpinned build instructions have moved [here](https://github.com/AntelopeIO/leap/blob/main/README.md#unpinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/main/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/main/README.md#step-3---build) before you build.
|
||||
The unpinned build instructions have moved [here](https://github.com/AntelopeIO/leap/blob/release/3.2/README.md#unpinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/release/3.2/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/release/3.2/README.md#step-3---build) before you build.
|
||||
|
||||
### Running Tests
|
||||
Documentation on available test suites and how to run them has moved [here](https://github.com/AntelopeIO/leap/blob/main/README.md#test).
|
||||
Documentation on available test suites and how to run them has moved [here](https://github.com/AntelopeIO/leap/blob/release/3.2/README.md#test).
|
||||
|
||||
@@ -13,6 +13,7 @@ For information on specific plugins, just select from the list below:
|
||||
* [`db_size_api_plugin`](db_size_api_plugin/index.md)
|
||||
* [`http_client_plugin`](http_client_plugin/index.md)
|
||||
* [`http_plugin`](http_plugin/index.md)
|
||||
* [`login_plugin`](login_plugin/index.md)
|
||||
* [`net_api_plugin`](net_api_plugin/index.md)
|
||||
* [`net_plugin`](net_plugin/index.md)
|
||||
* [`producer_plugin`](producer_plugin/index.md)
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
## Description
|
||||
|
||||
The `login_plugin` supports the concept of applications authenticating with the Antelope blockchain. The `login_plugin` API allows an application to verify whether an account is allowed to sign in order to satisfy a specified authority.
|
||||
|
||||
## Usage
|
||||
|
||||
```console
|
||||
# config.ini
|
||||
plugin = eosio::login_plugin
|
||||
[options]
|
||||
```
|
||||
```sh
|
||||
# command-line
|
||||
nodeos ... --plugin eosio::login_plugin [options]
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
These can be specified from both the `nodeos` command-line or the `config.ini` file:
|
||||
|
||||
```console
|
||||
Config Options for eosio::login_plugin:
|
||||
--max-login-requests arg (=1000000) The maximum number of pending login
|
||||
requests
|
||||
--max-login-timeout arg (=60) The maximum timeout for pending login
|
||||
requests (in seconds)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
* [`chain_plugin`](../chain_plugin/index.md)
|
||||
* [`http_plugin`](../http_plugin/index.md)
|
||||
|
||||
### Load Dependency Examples
|
||||
|
||||
```console
|
||||
# config.ini
|
||||
plugin = eosio::chain_plugin
|
||||
[options]
|
||||
plugin = eosio::http_plugin
|
||||
[options]
|
||||
```
|
||||
```sh
|
||||
# command-line
|
||||
nodeos ... --plugin eosio::chain_plugin [options] \
|
||||
--plugin eosio::http_plugin [options]
|
||||
```
|
||||
@@ -91,6 +91,11 @@ Config Options for eosio::wallet_plugin:
|
||||
number of seconds of inactivity.
|
||||
Activity is defined as any wallet
|
||||
command e.g. list-wallets.
|
||||
--yubihsm-url URL Override default URL of
|
||||
http://localhost:12345 for connecting
|
||||
to yubihsm-connector
|
||||
--yubihsm-authkey key_num Enables YubiHSM support using given
|
||||
Authkey
|
||||
|
||||
Application Config Options:
|
||||
--plugin arg Plugin(s) to enable, may be specified
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
content_title: How To Attach a YubiHSM Hard Wallet
|
||||
link_text: How To Attach a YubiHSM Hard Wallet
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Attach a YubiHSM as a hard wallet
|
||||
|
||||
## Before you begin
|
||||
|
||||
* Install the currently supported version of `keosd`
|
||||
|
||||
* Install YubiHSM2 Software Toolkit (YubiHSM2 SDK)
|
||||
|
||||
* Create an AuthKey with at least the following Capabilities:
|
||||
|
||||
* sign-ecdsa
|
||||
* generate-asymmetric-key
|
||||
* export-wrapped
|
||||
|
||||
* **Delete the default AuthKey**
|
||||
|
||||
[[warning | Security]]
|
||||
| It is extremely important to create a new AuthKey and remove the default AuthKey before proceed to the following steps.
|
||||
|
||||
## Steps
|
||||
|
||||
### Configure `keosd`
|
||||
|
||||
There are two options to connect `keosd` to YubiHSM:
|
||||
|
||||
#### Using a YubiHSM connector
|
||||
|
||||
By default, `keosd` will connect to the YubiHSM connector on the default host and port. If a non-default URL is used, set the `--yubihsm-url` option or `yubihsm-url` in `config.ini` with the correct connector URL
|
||||
|
||||
#### Directly connect via USB
|
||||
|
||||
`keosd` also can directly connect to YubiHSM via USB protocol
|
||||
|
||||
If this option is used, set `keosd` startup option as the below:
|
||||
|
||||
```sh
|
||||
--yubihsm-url=ysb://
|
||||
```
|
||||
|
||||
### Start `keosd` with AuthKey:
|
||||
|
||||
```sh
|
||||
--yubihsm-authkey Your_AuthKey_Object_Number
|
||||
```
|
||||
|
||||
if a YubiHSM connector is used, check the YubiHSM connector is up and running by visiting YubiHSM URL:
|
||||
http://YubiHSM_HOST:YubiHSM_PORT/connector/status ((Default HOST and Port: http://127.0.0.1:12345)
|
||||
|
||||
You should see something like this:
|
||||
|
||||
```console
|
||||
status=OK
|
||||
serial=*
|
||||
version=2.0.0
|
||||
pid=666
|
||||
address=localhost
|
||||
port=12345
|
||||
```
|
||||
|
||||
### Unlock YubiHSM wallet with the password of AuthKey using the following option:
|
||||
|
||||
```sh
|
||||
cleos wallet unlock -n YubiHSM --password YOUR_AUTHKEY_PASSWORD
|
||||
```
|
||||
|
||||
After unlocking the wallet, you can use `cleos wallet` commands as usual. Beware as a part of security mechanism, some wallet subcommands, such as retrieve private keys, or remove a key, are not supported when a YubiHSM is used
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
content_title: Keosd How-to Guides
|
||||
---
|
||||
|
||||
* [How to attach a YubiHSM hard wallet](how-to-attach-a-yubihsm-hard-wallet.md)
|
||||
@@ -26,3 +26,23 @@ set(ENABLE_PROFILE OFF CACHE BOOL "Enable for profile builds")
|
||||
if(eos-vm IN_LIST EOSIO_WASM_RUNTIMES OR eos-vm-jit IN_LIST EOSIO_WASM_RUNTIMES)
|
||||
add_subdirectory( eos-vm )
|
||||
endif()
|
||||
|
||||
#yubihsm's openssl discovery is via pkg-config instead of find_package. Help it out on macOS otherwise openssl's pkgconfig
|
||||
# files may not be found down in the /opt/homebrew/opt directory
|
||||
if(APPLE)
|
||||
get_filename_component(OPENSSL_LIB_PATH "${OPENSSL_CRYPTO_LIBRARY}" DIRECTORY)
|
||||
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${OPENSSL_LIB_PATH}/pkgconfig")
|
||||
endif()
|
||||
set(ENABLE_STATIC ON)
|
||||
set(CMAKE_MACOSX_RPATH OFF)
|
||||
set(BUILD_ONLY_LIB ON CACHE BOOL "Library only build")
|
||||
message(STATUS "Starting yubihsm configuration...")
|
||||
add_subdirectory( yubihsm EXCLUDE_FROM_ALL )
|
||||
target_compile_options(yubihsm_static PRIVATE -fno-lto -fcommon)
|
||||
message(STATUS "yubihsm configuration complete")
|
||||
|
||||
get_property(_CTEST_CUSTOM_TESTS_IGNORE GLOBAL PROPERTY CTEST_CUSTOM_TESTS_IGNORE)
|
||||
set_property(GLOBAL PROPERTY CTEST_CUSTOM_TESTS_IGNORE
|
||||
"change_authkey import_ed decrypt_ec decrypt_rsa ssh logs generate_rsa import_ec echo\
|
||||
yubico_otp wrap_data wrap info import_rsa import_authkey generate_hmac generate_ec\
|
||||
attest pbkdf2 parsing ${_CTEST_CUSTOM_TESTS_IGNORE}")
|
||||
|
||||
@@ -483,6 +483,7 @@ struct controller_impl {
|
||||
}
|
||||
|
||||
auto blog_head = blog.head();
|
||||
auto blog_head_time = blog_head ? blog_head->timestamp.to_time_point() : fork_db.root()->header.timestamp.to_time_point();
|
||||
replaying = true;
|
||||
auto start_block_num = head->block_num + 1;
|
||||
auto start = fc::time_point::now();
|
||||
@@ -820,10 +821,7 @@ struct controller_impl {
|
||||
});
|
||||
}
|
||||
|
||||
void add_to_snapshot( const snapshot_writer_ptr& snapshot ) {
|
||||
// clear in case the previous call to clear did not finish in time of deadline
|
||||
clear_expired_input_transactions( fc::time_point::maximum() );
|
||||
|
||||
void add_to_snapshot( const snapshot_writer_ptr& snapshot ) const {
|
||||
snapshot->write_section<chain_snapshot_header>([this]( auto §ion ){
|
||||
section.add_row(chain_snapshot_header(), db);
|
||||
});
|
||||
@@ -996,7 +994,7 @@ struct controller_impl {
|
||||
);
|
||||
}
|
||||
|
||||
sha256 calculate_integrity_hash() {
|
||||
sha256 calculate_integrity_hash() const {
|
||||
sha256::encoder enc;
|
||||
auto hash_writer = std::make_shared<integrity_hash_snapshot_writer>(enc);
|
||||
add_to_snapshot(hash_writer);
|
||||
@@ -2422,7 +2420,7 @@ struct controller_impl {
|
||||
//Look for expired transactions in the deduplication list, and remove them.
|
||||
auto& transaction_idx = db.get_mutable_index<transaction_multi_index>();
|
||||
const auto& dedupe_index = transaction_idx.indices().get<by_expiration>();
|
||||
auto now = self.is_building_block() ? self.pending_block_time() : self.head_block_time();
|
||||
auto now = self.pending_block_time();
|
||||
const auto total = dedupe_index.size();
|
||||
uint32_t num_removed = 0;
|
||||
while( (!dedupe_index.empty()) && ( now > fc::time_point(dedupe_index.begin()->expiration) ) ) {
|
||||
@@ -3134,11 +3132,11 @@ block_id_type controller::get_block_id_for_num( uint32_t block_num )const { try
|
||||
return id;
|
||||
} FC_CAPTURE_AND_RETHROW( (block_num) ) }
|
||||
|
||||
sha256 controller::calculate_integrity_hash() { try {
|
||||
sha256 controller::calculate_integrity_hash()const { try {
|
||||
return my->calculate_integrity_hash();
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
void controller::write_snapshot( const snapshot_writer_ptr& snapshot ) {
|
||||
void controller::write_snapshot( const snapshot_writer_ptr& snapshot ) const {
|
||||
EOS_ASSERT( !my->pending, block_validate_exception, "cannot take a consistent snapshot with a pending block" );
|
||||
return my->add_to_snapshot(snapshot);
|
||||
}
|
||||
|
||||
@@ -257,8 +257,8 @@ namespace eosio { namespace chain {
|
||||
|
||||
block_id_type get_block_id_for_num( uint32_t block_num )const;
|
||||
|
||||
sha256 calculate_integrity_hash();
|
||||
void write_snapshot( const snapshot_writer_ptr& snapshot );
|
||||
sha256 calculate_integrity_hash()const;
|
||||
void write_snapshot( const snapshot_writer_ptr& snapshot )const;
|
||||
|
||||
bool sender_avoids_whitelist_blacklist_enforcement( account_name sender )const;
|
||||
void check_actor_list( const flat_set<account_name>& actors )const;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// https://github.com/CLIUtils/CLI11
|
||||
//
|
||||
// This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts
|
||||
// from: b19d133
|
||||
// from: 1d3b0a7
|
||||
//
|
||||
// CLI11 2.2.0 Copyright (c) 2017-2022 University of Cincinnati, developed by Henry
|
||||
// Schreiner under NSF AWARD 1414736. All rights reserved.
|
||||
@@ -34,28 +34,28 @@
|
||||
#pragma once
|
||||
|
||||
// Standard combined includes:
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
#include <type_traits>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <locale>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
#include <tuple>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <set>
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#define CLI11_VERSION_MAJOR 2
|
||||
@@ -9420,134 +9420,4 @@ inline std::string Formatter::make_option_usage(const Option *opt) const {
|
||||
|
||||
|
||||
|
||||
|
||||
class LeapFormatter : public Formatter {
|
||||
// pseudographics - to draw subcommand tree
|
||||
const char* tree_line = u8"\u2502";
|
||||
const char* tree_angle = u8"\u2514";
|
||||
const char* tree_fork = u8"\u251C";
|
||||
|
||||
public:
|
||||
LeapFormatter() : Formatter() {
|
||||
// this gives better, more compact display
|
||||
column_width(25);
|
||||
}
|
||||
LeapFormatter(const LeapFormatter&) = default;
|
||||
LeapFormatter(LeapFormatter&&) = default;
|
||||
|
||||
/// This prints out all the subcommands
|
||||
virtual std::string make_subcommands(const App* app, AppFormatMode mode) const {
|
||||
std::stringstream out;
|
||||
|
||||
std::vector<const App*> subcommands = app->get_subcommands({});
|
||||
|
||||
// Make a list in definition order of the groups seen
|
||||
std::vector<std::string> subcmd_groups_seen;
|
||||
for(const App* com: subcommands) {
|
||||
if(com->get_name().empty()) {
|
||||
if(!com->get_group().empty()) {
|
||||
out << make_expanded(com);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
std::string group_key = com->get_group();
|
||||
if(!group_key.empty() &&
|
||||
std::find_if(subcmd_groups_seen.begin(), subcmd_groups_seen.end(), [&group_key](std::string a) {
|
||||
return detail::to_lower(a) == detail::to_lower(group_key);
|
||||
}) == subcmd_groups_seen.end())
|
||||
subcmd_groups_seen.push_back(group_key);
|
||||
}
|
||||
|
||||
// For each group, filter out and print subcommands
|
||||
for(const std::string& group: subcmd_groups_seen) {
|
||||
if(mode != AppFormatMode::SubCompact) {// do not show "Subcommands" header for nested tems in compact mode
|
||||
out << "\n"
|
||||
<< group << ":\n";
|
||||
}
|
||||
std::vector<const App*> subcommands_group = app->get_subcommands([&group](const App* sub_app) {
|
||||
return detail::to_lower(sub_app->get_group()) == detail::to_lower(group);
|
||||
});
|
||||
for(const App* new_com: subcommands_group) {
|
||||
if(new_com->get_name().empty())
|
||||
continue;
|
||||
|
||||
std::string tree_symbol = (subcommands_group.back() == new_com ? tree_angle : tree_fork);
|
||||
std::string line_symbol = (subcommands_group.back() == new_com ? "" : tree_line);
|
||||
std::string subc_symbol = "";
|
||||
|
||||
const App* parent = app->get_parent();
|
||||
if(parent != nullptr) {
|
||||
std::vector<const App*> sc_group = parent->get_subcommands([&group](const App* sub_app) {
|
||||
return detail::to_lower(sub_app->get_group()) == detail::to_lower(group);
|
||||
});
|
||||
if(sc_group.back() != app) {
|
||||
subc_symbol = tree_line;
|
||||
}
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case AppFormatMode::All:
|
||||
out << tree_symbol << new_com->help(new_com->get_name(), AppFormatMode::Sub);
|
||||
out << "\n";
|
||||
break;
|
||||
case AppFormatMode::AllCompact:
|
||||
|
||||
out << tree_symbol << new_com->help(new_com->get_name(), AppFormatMode::SubCompact);
|
||||
out << line_symbol;
|
||||
out << "\n";
|
||||
break;
|
||||
case AppFormatMode::Normal:
|
||||
case AppFormatMode::Sub:
|
||||
out << make_subcommand(new_com);
|
||||
break;
|
||||
case AppFormatMode::SubCompact:
|
||||
out << tree_symbol << make_expanded(new_com, mode);
|
||||
break;
|
||||
default:
|
||||
throw HorribleError("Internal error: unknown help type requested");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
/// This prints out a subcommand in help-all
|
||||
virtual std::string make_expanded(const App* sub, AppFormatMode mode = AppFormatMode::Sub) const {
|
||||
std::stringstream out;
|
||||
std::string tmp;
|
||||
std::string subc_symbol = " ";
|
||||
if(mode == AppFormatMode::SubCompact) {
|
||||
detail::format_help(out, sub->get_display_name(true), sub->get_description(), column_width_);
|
||||
out << make_subcommands(sub, mode);
|
||||
} else {
|
||||
out << sub->get_display_name(true) << "\n";
|
||||
out << make_description(sub);
|
||||
if(sub->get_name().empty() && !sub->get_aliases().empty()) {
|
||||
detail::format_aliases(out, sub->get_aliases(), column_width_ + 2);
|
||||
}
|
||||
out << make_positionals(sub);
|
||||
out << make_groups(sub, mode);
|
||||
out << make_subcommands(sub, mode);
|
||||
}
|
||||
|
||||
// Drop blank spaces
|
||||
tmp = detail::find_and_replace(out.str(), "\n\n", "\n");
|
||||
tmp = tmp.substr(0, tmp.size() - 1);// Remove the final '\n'
|
||||
|
||||
//
|
||||
auto group = sub->get_parent()->get_group();
|
||||
std::vector<const App*> sc_group = sub->get_parent()->get_subcommands(
|
||||
[&group](const App* sub_app) { return detail::to_lower(sub_app->get_group()) == detail::to_lower(group); });
|
||||
|
||||
if(sc_group.back() != sub) {
|
||||
subc_symbol = tree_line;
|
||||
}
|
||||
|
||||
// Indent all but the first line (the name)
|
||||
return detail::find_and_replace(tmp, "\n", "\n" + subc_symbol + " ") + "\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace CLI
|
||||
|
||||
+1
-1
Submodule libraries/eos-vm updated: 8345005a9d...7db4b33fa9
@@ -29,9 +29,9 @@ target_include_directories(secp256k1
|
||||
target_link_libraries(secp256k1 PRIVATE secp256k1-internal)
|
||||
|
||||
install( TARGETS secp256k1
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} COMPONENT dev EXCLUDE_FROM_ALL
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} COMPONENT dev EXCLUDE_FROM_ALL
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} COMPONENT dev EXCLUDE_FROM_ALL
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} ${INSTALL_COMPONENT_ARGS}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} ${INSTALL_COMPONENT_ARGS}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} ${INSTALL_COMPONENT_ARGS}
|
||||
)
|
||||
|
||||
add_executable(secp256k1-bench secp256k1/src/bench.c)
|
||||
|
||||
Submodule
+1
Submodule libraries/yubihsm added at 9189fdb92c
+2
-2
@@ -61,13 +61,13 @@ set(CPACK_DEBIAN_BASE_FILE_NAME "${CPACK_DEBIAN_FILE_NAME}.deb")
|
||||
string(REGEX REPLACE "^(${CMAKE_PROJECT_NAME})" "\\1-dev" CPACK_DEBIAN_DEV_FILE_NAME "${CPACK_DEBIAN_BASE_FILE_NAME}")
|
||||
|
||||
#deb package tooling will be unable to detect deps for the dev package. llvm is tricky since we don't know what package could have been used; try to figure it out
|
||||
set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "libboost-all-dev, libssl-dev, libgmp-dev")
|
||||
set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "libboost-all-dev;libssl-dev;libgmp-dev")
|
||||
find_program(DPKG_QUERY "dpkg-query")
|
||||
if(DPKG_QUERY AND OS_RELEASE MATCHES "\n?ID=\"?ubuntu" AND LLVM_CMAKE_DIR)
|
||||
execute_process(COMMAND "${DPKG_QUERY}" -S "${LLVM_CMAKE_DIR}" COMMAND cut -d: -f1 RESULT_VARIABLE LLVM_PKG_FIND_RESULT OUTPUT_VARIABLE LLVM_PKG_FIND_OUTPUT)
|
||||
if(LLVM_PKG_FIND_OUTPUT)
|
||||
string(STRIP "${LLVM_PKG_FIND_OUTPUT}" LLVM_PKG_FIND_OUTPUT)
|
||||
string(APPEND CPACK_DEBIAN_DEV_PACKAGE_DEPENDS ", ${LLVM_PKG_FIND_OUTPUT}")
|
||||
list(APPEND CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "${LLVM_PKG_FIND_OUTPUT}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -14,5 +14,6 @@ add_subdirectory(wallet_plugin)
|
||||
add_subdirectory(wallet_api_plugin)
|
||||
add_subdirectory(txn_test_gen_plugin)
|
||||
add_subdirectory(db_size_api_plugin)
|
||||
add_subdirectory(login_plugin)
|
||||
add_subdirectory(test_control_plugin)
|
||||
add_subdirectory(test_control_api_plugin)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 3
|
||||
ColumnLimit: 120
|
||||
PointerAlignment: Left
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
@@ -0,0 +1,7 @@
|
||||
file(GLOB HEADERS "include/eosio/login_plugin/*.hpp")
|
||||
add_library( login_plugin
|
||||
login_plugin.cpp
|
||||
${HEADERS} )
|
||||
|
||||
target_link_libraries( login_plugin chain_plugin http_plugin appbase )
|
||||
target_include_directories( login_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
#include <eosio/chain_plugin/chain_plugin.hpp>
|
||||
#include <eosio/http_plugin/http_plugin.hpp>
|
||||
|
||||
#include <appbase/application.hpp>
|
||||
#include <eosio/chain/controller.hpp>
|
||||
|
||||
namespace eosio {
|
||||
|
||||
class login_plugin : public plugin<login_plugin> {
|
||||
public:
|
||||
APPBASE_PLUGIN_REQUIRES((chain_plugin)(http_plugin))
|
||||
|
||||
login_plugin();
|
||||
virtual ~login_plugin();
|
||||
|
||||
virtual void set_program_options(options_description&, options_description&) override;
|
||||
void plugin_initialize(const variables_map&);
|
||||
void plugin_startup();
|
||||
void plugin_shutdown();
|
||||
|
||||
struct start_login_request_params {
|
||||
chain::time_point_sec expiration_time;
|
||||
};
|
||||
|
||||
struct start_login_request_results {
|
||||
chain::public_key_type server_ephemeral_pub_key;
|
||||
};
|
||||
|
||||
struct finalize_login_request_params {
|
||||
chain::public_key_type server_ephemeral_pub_key;
|
||||
chain::public_key_type client_ephemeral_pub_key;
|
||||
chain::permission_level permission;
|
||||
std::string data;
|
||||
std::vector<chain::signature_type> signatures;
|
||||
};
|
||||
|
||||
struct finalize_login_request_results {
|
||||
chain::sha256 digest{};
|
||||
flat_set<chain::public_key_type> recovered_keys{};
|
||||
bool permission_satisfied = false;
|
||||
std::string error{};
|
||||
};
|
||||
|
||||
struct do_not_use_gen_r1_key_params {};
|
||||
|
||||
struct do_not_use_gen_r1_key_results {
|
||||
chain::public_key_type pub_key;
|
||||
chain::private_key_type priv_key;
|
||||
};
|
||||
|
||||
struct do_not_use_sign_params {
|
||||
chain::private_key_type priv_key;
|
||||
chain::bytes data;
|
||||
};
|
||||
|
||||
struct do_not_use_sign_results {
|
||||
chain::signature_type sig;
|
||||
};
|
||||
|
||||
struct do_not_use_get_secret_params {
|
||||
chain::public_key_type pub_key;
|
||||
chain::private_key_type priv_key;
|
||||
};
|
||||
|
||||
struct do_not_use_get_secret_results {
|
||||
chain::sha512 secret;
|
||||
};
|
||||
|
||||
start_login_request_results start_login_request(const start_login_request_params&);
|
||||
finalize_login_request_results finalize_login_request(const finalize_login_request_params&);
|
||||
|
||||
do_not_use_gen_r1_key_results do_not_use_gen_r1_key(const do_not_use_gen_r1_key_params&);
|
||||
do_not_use_sign_results do_not_use_sign(const do_not_use_sign_params&);
|
||||
do_not_use_get_secret_results do_not_use_get_secret(const do_not_use_get_secret_params&);
|
||||
|
||||
private:
|
||||
unique_ptr<class login_plugin_impl> my;
|
||||
};
|
||||
|
||||
} // namespace eosio
|
||||
|
||||
FC_REFLECT(eosio::login_plugin::start_login_request_params, (expiration_time))
|
||||
FC_REFLECT(eosio::login_plugin::start_login_request_results, (server_ephemeral_pub_key))
|
||||
FC_REFLECT(eosio::login_plugin::finalize_login_request_params,
|
||||
(server_ephemeral_pub_key)(client_ephemeral_pub_key)(permission)(data)(signatures))
|
||||
FC_REFLECT(eosio::login_plugin::finalize_login_request_results, (digest)(recovered_keys)(permission_satisfied)(error))
|
||||
|
||||
FC_REFLECT_EMPTY(eosio::login_plugin::do_not_use_gen_r1_key_params)
|
||||
FC_REFLECT(eosio::login_plugin::do_not_use_gen_r1_key_results, (pub_key)(priv_key))
|
||||
FC_REFLECT(eosio::login_plugin::do_not_use_sign_params, (priv_key)(data))
|
||||
FC_REFLECT(eosio::login_plugin::do_not_use_sign_results, (sig))
|
||||
FC_REFLECT(eosio::login_plugin::do_not_use_get_secret_params, (pub_key)(priv_key))
|
||||
FC_REFLECT(eosio::login_plugin::do_not_use_get_secret_results, (secret))
|
||||
@@ -0,0 +1,160 @@
|
||||
#include <eosio/chain/authorization_manager.hpp>
|
||||
#include <eosio/chain/exceptions.hpp>
|
||||
#include <eosio/login_plugin/login_plugin.hpp>
|
||||
|
||||
#include <fc/io/json.hpp>
|
||||
|
||||
namespace eosio {
|
||||
|
||||
static appbase::abstract_plugin& _login_plugin = app().register_plugin<login_plugin>();
|
||||
|
||||
using namespace eosio;
|
||||
|
||||
struct login_request {
|
||||
chain::private_key_type server_ephemeral_priv_key{};
|
||||
chain::public_key_type server_ephemeral_pub_key{};
|
||||
chain::time_point_sec expiration_time;
|
||||
};
|
||||
|
||||
struct login_request_pub_key_index {};
|
||||
struct login_request_time_index {};
|
||||
|
||||
using login_request_container = boost::multi_index_container<
|
||||
login_request,
|
||||
indexed_by< //
|
||||
ordered_unique<tag<login_request_pub_key_index>,
|
||||
member<login_request, chain::public_key_type, &login_request::server_ephemeral_pub_key>>,
|
||||
ordered_non_unique<tag<login_request_time_index>,
|
||||
member<login_request, chain::time_point_sec, &login_request::expiration_time>> //
|
||||
>>;
|
||||
|
||||
class login_plugin_impl {
|
||||
public:
|
||||
login_request_container requests{};
|
||||
uint32_t max_login_requests = 1000000;
|
||||
uint32_t max_login_timeout = 60;
|
||||
|
||||
void expire_requests() {
|
||||
auto& index = requests.get<login_request_time_index>();
|
||||
auto now = fc::time_point::now();
|
||||
for (auto it = index.begin(); it != index.end() && it->expiration_time < now; it = index.erase(it))
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
login_plugin::login_plugin() : my{std::make_unique<login_plugin_impl>()} {}
|
||||
login_plugin::~login_plugin() {}
|
||||
|
||||
void login_plugin::set_program_options(options_description&, options_description& cfg) {
|
||||
cfg.add_options() //
|
||||
("max-login-requests", bpo::value<uint32_t>()->default_value(1000000),
|
||||
"The maximum number of pending login requests") //
|
||||
("max-login-timeout", bpo::value<uint32_t>()->default_value(60),
|
||||
"The maximum timeout for pending login requests (in seconds)");
|
||||
}
|
||||
|
||||
void login_plugin::plugin_initialize(const variables_map& options) {
|
||||
my->max_login_requests = options.at("max-login-requests").as<uint32_t>();
|
||||
my->max_login_timeout = options.at("max-login-timeout").as<uint32_t>();
|
||||
}
|
||||
|
||||
#define CALL(call_name, http_response_code) \
|
||||
{ \
|
||||
std::string("/v1/login/" #call_name), [this](string, string body, url_response_callback cb) mutable { \
|
||||
try { \
|
||||
if (body.empty()) \
|
||||
body = "{}"; \
|
||||
fc::variant result( call_name(fc::json::from_string(body).as<login_plugin::call_name##_params>()) ); \
|
||||
cb(http_response_code, fc::time_point::maximum(), std::move(result)); \
|
||||
} catch (...) { \
|
||||
http_plugin::handle_exception("login", #call_name, body, cb); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
void login_plugin::plugin_startup() {
|
||||
ilog("starting login_plugin");
|
||||
app().get_plugin<http_plugin>().add_api({
|
||||
CALL(start_login_request, 200), //
|
||||
CALL(finalize_login_request, 200),
|
||||
// CALL(do_not_use_gen_r1_key, 200), //
|
||||
// CALL(do_not_use_sign, 200), //
|
||||
// CALL(do_not_use_get_secret, 200), //
|
||||
});
|
||||
}
|
||||
|
||||
void login_plugin::plugin_shutdown() {}
|
||||
|
||||
login_plugin::start_login_request_results
|
||||
login_plugin::start_login_request(const login_plugin::start_login_request_params& params) {
|
||||
my->expire_requests();
|
||||
EOS_ASSERT(params.expiration_time > fc::time_point::now(), fc::timeout_exception,
|
||||
"Requested expiration time ${expiration_time} is in the past",
|
||||
("expiration_time", params.expiration_time));
|
||||
EOS_ASSERT(my->requests.size() < my->max_login_requests, fc::timeout_exception, "Too many pending login requests");
|
||||
login_request request;
|
||||
request.server_ephemeral_priv_key = chain::private_key_type::generate_r1();
|
||||
request.server_ephemeral_pub_key = request.server_ephemeral_priv_key.get_public_key();
|
||||
request.expiration_time =
|
||||
std::min(params.expiration_time, fc::time_point_sec{fc::time_point::now()} + my->max_login_timeout);
|
||||
my->requests.insert(request);
|
||||
return {request.server_ephemeral_pub_key};
|
||||
}
|
||||
|
||||
login_plugin::finalize_login_request_results
|
||||
login_plugin::finalize_login_request(const login_plugin::finalize_login_request_params& params) {
|
||||
finalize_login_request_results result;
|
||||
my->expire_requests();
|
||||
auto& index = my->requests.get<login_request_pub_key_index>();
|
||||
auto it = index.find(params.server_ephemeral_pub_key);
|
||||
if (it == index.end()) {
|
||||
result.error = "server_ephemeral_pub_key expired or not found";
|
||||
return result;
|
||||
}
|
||||
auto request = *it;
|
||||
index.erase(it);
|
||||
|
||||
auto shared_secret = request.server_ephemeral_priv_key.generate_shared_secret(params.client_ephemeral_pub_key);
|
||||
|
||||
chain::bytes combined_data(1024 * 1024);
|
||||
chain::datastream<char*> sig_data_ds{combined_data.data(), combined_data.size()};
|
||||
fc::raw::pack(sig_data_ds, params.permission);
|
||||
fc::raw::pack(sig_data_ds, shared_secret);
|
||||
fc::raw::pack(sig_data_ds, params.data);
|
||||
combined_data.resize(sig_data_ds.tellp());
|
||||
|
||||
result.digest = chain::sha256::hash(combined_data);
|
||||
for (auto& sig : params.signatures)
|
||||
result.recovered_keys.insert(chain::public_key_type{sig, result.digest});
|
||||
|
||||
try {
|
||||
auto noop_checktime = [] {};
|
||||
auto& chain = app().get_plugin<chain_plugin>().chain();
|
||||
chain.get_authorization_manager().check_authorization( //
|
||||
params.permission.actor, params.permission.permission, result.recovered_keys, {}, fc::microseconds(0),
|
||||
noop_checktime, true);
|
||||
result.permission_satisfied = true;
|
||||
} catch (...) {
|
||||
result.error = "keys do not satisfy permission";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
login_plugin::do_not_use_gen_r1_key_results
|
||||
login_plugin::do_not_use_gen_r1_key(const login_plugin::do_not_use_gen_r1_key_params& params) {
|
||||
auto priv = chain::private_key_type::generate_r1();
|
||||
return {priv.get_public_key(), priv};
|
||||
}
|
||||
|
||||
login_plugin::do_not_use_sign_results
|
||||
login_plugin::do_not_use_sign(const login_plugin::do_not_use_sign_params& params) {
|
||||
return {params.priv_key.sign(chain::sha256::hash(params.data))};
|
||||
}
|
||||
|
||||
login_plugin::do_not_use_get_secret_results
|
||||
login_plugin::do_not_use_get_secret(const login_plugin::do_not_use_get_secret_params& params) {
|
||||
return {params.priv_key.generate_shared_secret(params.pub_key)};
|
||||
}
|
||||
|
||||
} // namespace eosio
|
||||
+2
-3
@@ -59,8 +59,7 @@ namespace eosio::resource_monitor {
|
||||
|
||||
if ( info.available < fs.shutdown_available ) {
|
||||
if (output_threshold_warning) {
|
||||
elog("Space usage warning: ${path}'s file system exceeded threshold ${threshold}%, available: ${available}, Capacity: ${capacity}, shutdown_available: ${shutdown_available}",
|
||||
("path", fs.path_name.string())("threshold", shutdown_threshold)("available", info.available)("capacity", info.capacity)("shutdown_available", fs.shutdown_available));
|
||||
wlog("Space usage warning: ${path}'s file system exceeded threshold ${threshold}%, available: ${available}, Capacity: ${capacity}, shutdown_available: ${shutdown_available}", ("path", fs.path_name.string()) ("threshold", shutdown_threshold) ("available", info.available) ("capacity", info.capacity) ("shutdown_available", fs.shutdown_available));
|
||||
}
|
||||
return true;
|
||||
} else if ( info.available < fs.warning_available && output_threshold_warning ) {
|
||||
@@ -115,7 +114,7 @@ namespace eosio::resource_monitor {
|
||||
|
||||
void space_monitor_loop() {
|
||||
if ( is_threshold_exceeded() && shutdown_on_exceeded ) {
|
||||
elog("Shutting down, file system exceeded threshold");
|
||||
wlog("Shutting down");
|
||||
appbase::app().quit(); // This will gracefully stop Nodeos
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -570,14 +570,14 @@ struct state_history_plugin_impl : std::enable_shared_from_this<state_history_pl
|
||||
return;
|
||||
bool fresh = chain_state_log->begin_block() == chain_state_log->end_block();
|
||||
if (fresh)
|
||||
fc_ilog(_log, "Placing initial state in block ${n}", ("n", block_state->block_num));
|
||||
fc_ilog(_log, "Placing initial state in block ${n}", ("n", block_state->block->block_num()));
|
||||
|
||||
std::vector<table_delta> deltas = state_history::create_deltas(chain_plug->chain().db(), fresh);
|
||||
auto deltas_bin = state_history::zlib_compress_bytes(fc::raw::pack(deltas));
|
||||
state_history_log_header header{.magic = ship_magic(ship_current_version, 0),
|
||||
.block_id = block_state->id,
|
||||
.payload_size = sizeof(uint32_t) + deltas_bin.size()};
|
||||
chain_state_log->write_entry(header, block_state->header.previous, [&](auto& stream) {
|
||||
chain_state_log->write_entry(header, block_state->block->previous, [&](auto& stream) {
|
||||
// Compressed deltas now exceeds 4GB on one of the public chains. This length prefix
|
||||
// was intended to support adding additional fields in the future after the
|
||||
// packed deltas. For now we're going to ignore on read. The 0 is an attempt to signal
|
||||
@@ -694,12 +694,6 @@ void state_history_plugin::plugin_startup() {
|
||||
|
||||
try {
|
||||
my->thr = std::thread([ptr = my.get()] { ptr->ctx.run(); });
|
||||
auto bsp = my->chain_plug->chain().head_block_state();
|
||||
if( bsp && my->chain_state_log && my->chain_state_log->begin_block() == my->chain_state_log->end_block() ) {
|
||||
fc_ilog( _log, "Storing initial state on startup, this can take a considerable amount of time" );
|
||||
my->store_chain_state( bsp );
|
||||
fc_ilog( _log, "Done storing initial state on startup" );
|
||||
}
|
||||
my->listen();
|
||||
} catch (std::exception& ex) {
|
||||
appbase::app().quit();
|
||||
@@ -710,6 +704,7 @@ void state_history_plugin::plugin_shutdown() {
|
||||
my->applied_transaction_connection.reset();
|
||||
my->accepted_block_connection.reset();
|
||||
my->block_start_connection.reset();
|
||||
my->sessions.for_each([](auto& s) { s->close(); });
|
||||
my->stopping = true;
|
||||
my->trace_log->stop();
|
||||
my->chain_state_log->stop();
|
||||
|
||||
@@ -19,7 +19,11 @@ add_library( wallet_plugin
|
||||
wallet_plugin.cpp
|
||||
wallet_manager.cpp
|
||||
${SE_WALLET_SOURCES}
|
||||
yubihsm_wallet.cpp
|
||||
${HEADERS} )
|
||||
|
||||
target_link_libraries( wallet_plugin eosio_chain appbase ${security_framework} ${corefoundation_framework} ${localauthentication_framework} ${cocoa_framework})
|
||||
target_link_libraries( wallet_plugin yubihsm_static eosio_chain appbase ${security_framework} ${corefoundation_framework} ${localauthentication_framework} ${cocoa_framework})
|
||||
target_include_directories( wallet_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
|
||||
#sadly old cmake 2.8 support in yubihsm cmake prevents usage of target_include_directories there
|
||||
target_include_directories( wallet_plugin PRIVATE "${CMAKE_SOURCE_DIR}/libraries/yubihsm/lib" )
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <eosio/chain/types.hpp>
|
||||
#include <eosio/wallet_plugin/wallet_api.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace eosio::chain;
|
||||
|
||||
namespace eosio { namespace wallet {
|
||||
|
||||
namespace detail {
|
||||
struct yubihsm_wallet_impl;
|
||||
}
|
||||
|
||||
class yubihsm_wallet final : public wallet_api {
|
||||
public:
|
||||
yubihsm_wallet(const string& connector, const uint16_t authkey);
|
||||
~yubihsm_wallet();
|
||||
|
||||
private_key_type get_private_key(public_key_type pubkey) const override;
|
||||
|
||||
bool is_locked() const override;
|
||||
void lock() override;
|
||||
void unlock(string password) override;
|
||||
void check_password(string password) override;
|
||||
void set_password(string password) override;
|
||||
|
||||
map<public_key_type, private_key_type> list_keys() override;
|
||||
flat_set<public_key_type> list_public_keys() override;
|
||||
|
||||
bool import_key(string wif_key) override;
|
||||
string create_key(string key_type) override;
|
||||
bool remove_key(string key) override;
|
||||
|
||||
std::optional<signature_type> try_sign_digest(const digest_type digest, const public_key_type public_key) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<detail::yubihsm_wallet_impl> my;
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <eosio/wallet_plugin/wallet_plugin.hpp>
|
||||
#include <eosio/wallet_plugin/wallet_manager.hpp>
|
||||
#include <eosio/wallet_plugin/yubihsm_wallet.hpp>
|
||||
#include <eosio/chain/exceptions.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <chrono>
|
||||
@@ -26,6 +27,10 @@ void wallet_plugin::set_program_options(options_description& cli, options_descri
|
||||
"Timeout for unlocked wallet in seconds (default 900 (15 minutes)). "
|
||||
"Wallets will automatically lock after specified number of seconds of inactivity. "
|
||||
"Activity is defined as any wallet command e.g. list-wallets.")
|
||||
("yubihsm-url", bpo::value<string>()->value_name("URL"),
|
||||
"Override default URL of http://localhost:12345 for connecting to yubihsm-connector")
|
||||
("yubihsm-authkey", bpo::value<uint16_t>()->value_name("key_num"),
|
||||
"Enables YubiHSM support using given Authkey")
|
||||
;
|
||||
}
|
||||
|
||||
@@ -48,6 +53,15 @@ void wallet_plugin::plugin_initialize(const variables_map& options) {
|
||||
std::chrono::seconds t(timeout);
|
||||
wallet_manager_ptr->set_timeout(t);
|
||||
}
|
||||
if (options.count("yubihsm-authkey")) {
|
||||
uint16_t key = options.at("yubihsm-authkey").as<uint16_t>();
|
||||
string connector_endpoint = "http://localhost:12345";
|
||||
if(options.count("yubihsm-url"))
|
||||
connector_endpoint = options.at("yubihsm-url").as<string>();
|
||||
try {
|
||||
wallet_manager_ptr->own_and_use_wallet("YubiHSM", make_unique<yubihsm_wallet>(connector_endpoint, key));
|
||||
}FC_LOG_AND_RETHROW()
|
||||
}
|
||||
} FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
#include <appbase/application.hpp>
|
||||
|
||||
#include <eosio/wallet_plugin/yubihsm_wallet.hpp>
|
||||
#include <eosio/chain/exceptions.hpp>
|
||||
#include <yubihsm.h>
|
||||
|
||||
#include <fc/crypto/openssl.hpp>
|
||||
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
#include <boost/range/algorithm/copy.hpp>
|
||||
#include <boost/asio/posix/stream_descriptor.hpp>
|
||||
#include <boost/dll/runtime_symbol_info.hpp>
|
||||
|
||||
namespace eosio { namespace wallet {
|
||||
|
||||
using namespace fc::crypto::r1;
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct yubihsm_wallet_impl {
|
||||
using key_map_type = map<public_key_type,uint16_t>;
|
||||
|
||||
yubihsm_wallet_impl(const string& ep, const uint16_t ak) : endpoint(ep), authkey(ak) {
|
||||
yh_rc rc;
|
||||
if((rc = yh_init()))
|
||||
FC_THROW("yubihsm init failure: ${c}", ("c", yh_strerror(rc)));
|
||||
}
|
||||
|
||||
~yubihsm_wallet_impl() {
|
||||
lock();
|
||||
yh_exit();
|
||||
//bizarre, is there no way to destroy a yh_connector??
|
||||
|
||||
///XXX Probably a race condition on timer shutdown and appbase destruction
|
||||
}
|
||||
|
||||
bool is_locked() const {
|
||||
return !connector;
|
||||
}
|
||||
|
||||
key_map_type::iterator populate_key_map_with_keyid(const uint16_t key_id) {
|
||||
yh_rc rc;
|
||||
size_t blob_sz = 128;
|
||||
uint8_t blob[blob_sz];
|
||||
if((rc = yh_util_get_public_key(session, key_id, blob, &blob_sz, nullptr)))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "yh_util_get_public_key failed: ${m}", ("m", yh_strerror(rc)));
|
||||
if(blob_sz != 64)
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "unexpected pubkey size from yh_util_get_public_key");
|
||||
|
||||
///XXX This is junky and common with SE wallet; commonize it
|
||||
char serialized_pub_key[sizeof(public_key_data) + 1];
|
||||
serialized_pub_key[0] = 0x01; //means R1 key
|
||||
serialized_pub_key[1] = 0x02 + (blob[63]&1); //R1 header; even or odd Y
|
||||
memcpy(serialized_pub_key+2, blob, 32); //copy in the 32 bytes of X
|
||||
|
||||
public_key_type pub_key;
|
||||
fc::datastream<const char *> ds(serialized_pub_key, sizeof(serialized_pub_key));
|
||||
fc::raw::unpack(ds, pub_key);
|
||||
|
||||
return _keys.emplace(pub_key, key_id).first;
|
||||
}
|
||||
|
||||
void unlock(const string& password) {
|
||||
yh_rc rc;
|
||||
|
||||
try {
|
||||
if((rc = yh_init_connector(endpoint.c_str(), &connector)))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Failled to initialize yubihsm connector URL: ${c}", ("c", yh_strerror(rc)));
|
||||
if((rc = yh_connect(connector, 0)))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to connect to YubiHSM connector: ${m}", ("m", yh_strerror(rc)));
|
||||
if((rc = yh_create_session_derived(connector, authkey, (const uint8_t *)password.data(), password.size(), false, &session)))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to create YubiHSM session: ${m}", ("m", yh_strerror(rc)));
|
||||
if((rc = yh_authenticate_session(session)))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to authenticate YubiHSM session: ${m}", ("m", yh_strerror(rc)));
|
||||
|
||||
yh_object_descriptor authkey_desc;
|
||||
if((rc = yh_util_get_object_info(session, authkey, YH_AUTHENTICATION_KEY, &authkey_desc)))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to get authkey info: ${m}", ("m", yh_strerror(rc)));
|
||||
|
||||
authkey_caps = authkey_desc.capabilities;
|
||||
authkey_domains = authkey_desc.domains;
|
||||
|
||||
if(!yh_check_capability(&authkey_caps, "sign-ecdsa"))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Given authkey cannot perform signing");
|
||||
|
||||
size_t found_objects_n = 64*1024;
|
||||
yh_object_descriptor found_objs[found_objects_n];
|
||||
yh_capabilities find_caps;
|
||||
yh_string_to_capabilities("sign-ecdsa", &find_caps);
|
||||
if((rc = yh_util_list_objects(session, 0, YH_ASYMMETRIC_KEY, 0, &find_caps, YH_ALGO_EC_P256, nullptr, found_objs, &found_objects_n)))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "yh_util_list_objects failed: ${m}", ("m", yh_strerror(rc)));
|
||||
|
||||
for(size_t i = 0; i < found_objects_n; ++i)
|
||||
populate_key_map_with_keyid(found_objs[i].id);
|
||||
}
|
||||
catch(chain::wallet_exception& e) {
|
||||
lock();
|
||||
throw;
|
||||
}
|
||||
|
||||
prime_keepalive_timer();
|
||||
}
|
||||
|
||||
void lock() {
|
||||
if(session) {
|
||||
yh_util_close_session(session);
|
||||
yh_destroy_session(&session);
|
||||
}
|
||||
session = nullptr;
|
||||
if(connector)
|
||||
yh_disconnect(connector);
|
||||
//it would seem like this would leak-- there is no destroy() call for it. But I clearly can't reuse connectors
|
||||
// as that fails with a "Unable to find a suitable connector"
|
||||
connector = nullptr;
|
||||
|
||||
_keys.clear();
|
||||
keepalive_timer.cancel();
|
||||
}
|
||||
|
||||
void prime_keepalive_timer() {
|
||||
keepalive_timer.expires_at(std::chrono::steady_clock::now() + std::chrono::seconds(20));
|
||||
keepalive_timer.async_wait([this](const boost::system::error_code& ec){
|
||||
if(ec || !session)
|
||||
return;
|
||||
|
||||
uint8_t data, resp;
|
||||
yh_cmd resp_cmd;
|
||||
size_t resp_sz = 1;
|
||||
if(yh_send_secure_msg(session, YHC_ECHO, &data, 1, &resp_cmd, &resp, &resp_sz))
|
||||
lock();
|
||||
else
|
||||
prime_keepalive_timer();
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<signature_type> try_sign_digest(const digest_type d, const public_key_type public_key) {
|
||||
auto it = _keys.find(public_key);
|
||||
if(it == _keys.end())
|
||||
return std::optional<signature_type>();
|
||||
|
||||
size_t der_sig_sz = 128;
|
||||
uint8_t der_sig[der_sig_sz];
|
||||
yh_rc rc;
|
||||
if((rc = yh_util_sign_ecdsa(session, it->second, (uint8_t*)d.data(), d.data_size(), der_sig, &der_sig_sz))) {
|
||||
lock();
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "yh_util_sign_ecdsa failed: ${m}", ("m", yh_strerror(rc)));
|
||||
}
|
||||
|
||||
///XXX a lot of this below is similar to SE wallet; commonize it in non-junky way
|
||||
fc::ecdsa_sig sig = ECDSA_SIG_new();
|
||||
BIGNUM *r = BN_new(), *s = BN_new();
|
||||
BN_bin2bn(der_sig+4, der_sig[3], r);
|
||||
BN_bin2bn(der_sig+6+der_sig[3], der_sig[4+der_sig[3]+1], s);
|
||||
ECDSA_SIG_set0(sig, r, s);
|
||||
|
||||
char pub_key_shim_data[64];
|
||||
fc::datastream<char *> eds(pub_key_shim_data, sizeof(pub_key_shim_data));
|
||||
fc::raw::pack(eds, it->first);
|
||||
public_key_data* kd = (public_key_data*)(pub_key_shim_data+1);
|
||||
|
||||
compact_signature compact_sig;
|
||||
compact_sig = signature_from_ecdsa(key, *kd, sig, d);
|
||||
|
||||
char serialized_signature[sizeof(compact_sig) + 1];
|
||||
serialized_signature[0] = 0x01;
|
||||
memcpy(serialized_signature+1, compact_sig.data, sizeof(compact_sig));
|
||||
|
||||
signature_type final_signature;
|
||||
fc::datastream<const char *> ds(serialized_signature, sizeof(serialized_signature));
|
||||
fc::raw::unpack(ds, final_signature);
|
||||
return final_signature;
|
||||
}
|
||||
|
||||
public_key_type create() {
|
||||
if(!yh_check_capability(&authkey_caps, "generate-asymmetric-key"))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Given authkey cannot create keys");
|
||||
|
||||
yh_rc rc;
|
||||
uint16_t new_key_id = 0;
|
||||
yh_capabilities creation_caps = {};
|
||||
if(yh_string_to_capabilities("sign-ecdsa:export-wrapped", &creation_caps))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Cannot create caps mask");
|
||||
|
||||
try {
|
||||
if((rc = yh_util_generate_ec_key(session, &new_key_id, "keosd created key", authkey_domains, &creation_caps, YH_ALGO_EC_P256)))
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "yh_util_generate_ec_key failed: ${m}", ("m", yh_strerror(rc)));
|
||||
return populate_key_map_with_keyid(new_key_id)->first;
|
||||
}
|
||||
catch(chain::wallet_exception& e) {
|
||||
lock();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
yh_connector* connector = nullptr;
|
||||
yh_session* session = nullptr;
|
||||
string endpoint;
|
||||
uint16_t authkey;
|
||||
|
||||
map<public_key_type,uint16_t> _keys;
|
||||
|
||||
yh_capabilities authkey_caps;
|
||||
uint16_t authkey_domains;
|
||||
|
||||
boost::asio::steady_timer keepalive_timer{appbase::app().get_io_service()};
|
||||
fc::ec_key key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
yubihsm_wallet::yubihsm_wallet(const string& connector, const uint16_t authkey) : my(new detail::yubihsm_wallet_impl(connector, authkey)) {
|
||||
}
|
||||
|
||||
yubihsm_wallet::~yubihsm_wallet() {
|
||||
}
|
||||
|
||||
private_key_type yubihsm_wallet::get_private_key(public_key_type pubkey) const {
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Obtaining private key for a key stored in YubiHSM is impossible");
|
||||
}
|
||||
|
||||
bool yubihsm_wallet::is_locked() const {
|
||||
return my->is_locked();
|
||||
}
|
||||
void yubihsm_wallet::lock() {
|
||||
FC_ASSERT(!is_locked());
|
||||
my->lock();
|
||||
}
|
||||
|
||||
void yubihsm_wallet::unlock(string password) {
|
||||
my->unlock(password);
|
||||
}
|
||||
void yubihsm_wallet::check_password(string password) {
|
||||
//just leave this as a noop for now; remove_key from wallet_mgr calls through here
|
||||
}
|
||||
void yubihsm_wallet::set_password(string password) {
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "YubiHSM wallet cannot have a password set");
|
||||
}
|
||||
|
||||
map<public_key_type, private_key_type> yubihsm_wallet::list_keys() {
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "Getting the private keys from the YubiHSM wallet is impossible");
|
||||
}
|
||||
flat_set<public_key_type> yubihsm_wallet::list_public_keys() {
|
||||
flat_set<public_key_type> keys;
|
||||
boost::copy(my->_keys | boost::adaptors::map_keys, std::inserter(keys, keys.end()));
|
||||
return keys;
|
||||
}
|
||||
|
||||
bool yubihsm_wallet::import_key(string wif_key) {
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "It is not possible to import a key in to the YubiHSM wallet");
|
||||
}
|
||||
|
||||
string yubihsm_wallet::create_key(string key_type) {
|
||||
EOS_ASSERT(key_type.empty() || key_type == "R1", chain::unsupported_key_type_exception, "YubiHSM wallet only supports R1 keys");
|
||||
return my->create().to_string();
|
||||
}
|
||||
|
||||
bool yubihsm_wallet::remove_key(string key) {
|
||||
FC_ASSERT(!is_locked());
|
||||
FC_THROW_EXCEPTION(chain::wallet_exception, "YubiHSM wallet does not currently support removal of keys");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<signature_type> yubihsm_wallet::try_sign_digest(const digest_type digest, const public_key_type public_key) {
|
||||
return my->try_sign_digest(digest, public_key);
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -2759,16 +2759,8 @@ int main( int argc, char** argv ) {
|
||||
wallet_url = default_wallet_url;
|
||||
|
||||
CLI::App app{"Command Line Interface to EOSIO Client"};
|
||||
|
||||
// custom leap formatter
|
||||
auto fmt = std::make_shared<CLI::LeapFormatter>();
|
||||
app.formatter(fmt);
|
||||
|
||||
// enable help-all, display help on error
|
||||
app.set_help_all_flag("--help-all", "Show all help");
|
||||
app.failure_message(CLI::FailureMessage::help);
|
||||
app.require_subcommand();
|
||||
|
||||
// Hide obsolete options by putting them into a group with an empty name.
|
||||
app.add_option( "-H,--host", obsoleted_option_host_port, localized("The host where ${n} is running", ("n", node_executable_name)) )->group("");
|
||||
app.add_option( "-p,--port", obsoleted_option_host_port, localized("The port where ${n} is running", ("n", node_executable_name)) )->group("");
|
||||
|
||||
@@ -37,8 +37,8 @@ void chain_actions::setup(CLI::App& app) {
|
||||
sub->require_subcommand(1);
|
||||
|
||||
auto* build = sub->add_subcommand("build-info", "extract build environment information as JSON");
|
||||
build->add_option("--output-file,-o", opt->build_output_file, "write into specified file")->capture_default_str();
|
||||
build->add_flag("--print,-p", opt->build_just_print, "print to console");
|
||||
auto opt1 = build->add_option("--output-file,-o", opt->build_output_file, "write into specified file")->capture_default_str();
|
||||
auto opt2 = build->add_flag("--print,-p", opt->build_just_print, "print to console");
|
||||
build->require_option(1);
|
||||
|
||||
build->callback([&]() {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <cli11/CLI11.hpp>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
class leap_formatter : public CLI::Formatter {
|
||||
public:
|
||||
leap_formatter() : Formatter() {
|
||||
// 30 is default for CLI11, but seems like overkill
|
||||
column_width(25);
|
||||
}
|
||||
};
|
||||
@@ -12,17 +12,18 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "leap_formatter.hpp"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
|
||||
|
||||
CLI::App app{"Leap Command Line Utility"};
|
||||
|
||||
// custom leap formatter
|
||||
auto fmt = std::make_shared<CLI::LeapFormatter>();
|
||||
auto fmt = std::make_shared<leap_formatter>();
|
||||
app.formatter(fmt);
|
||||
|
||||
app.set_help_all_flag("--help-all", "Show all help");
|
||||
app.failure_message(CLI::FailureMessage::help);
|
||||
app.require_subcommand(1, 2);
|
||||
|
||||
// generics sc tree
|
||||
|
||||
@@ -26,6 +26,7 @@ endif()
|
||||
|
||||
target_link_libraries( ${NODE_EXECUTABLE_NAME}
|
||||
PRIVATE appbase version
|
||||
PRIVATE -Wl,${whole_archive_flag} login_plugin -Wl,${no_whole_archive_flag}
|
||||
PRIVATE -Wl,${whole_archive_flag} state_history_plugin -Wl,${no_whole_archive_flag}
|
||||
PRIVATE -Wl,${whole_archive_flag} trace_api_plugin -Wl,${no_whole_archive_flag}
|
||||
PRIVATE -Wl,${whole_archive_flag} chain_api_plugin -Wl,${no_whole_archive_flag}
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
apt-get update
|
||||
apt-get update --fix-missing
|
||||
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata
|
||||
apt-get -y install zip unzip libncurses5 wget git build-essential cmake curl libgmp-dev libssl-dev libzstd-dev time zlib1g-dev libtinfo-dev bzip2 libbz2-dev python3 file
|
||||
apt-get -y install zip unzip libncurses5 wget git build-essential cmake curl libcurl4-openssl-dev libgmp-dev libssl-dev libusb-1.0.0-dev libzstd-dev time pkg-config zlib1g-dev libtinfo-dev bzip2 libbz2-dev python3 file
|
||||
|
||||
@@ -346,8 +346,6 @@ def stepSetSystemContract():
|
||||
retry(args.cleos + 'push action eosio activate \'["4fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2"]\' -p eosio@active')
|
||||
# WTMSIG_BLOCK_SIGNATURES
|
||||
retry(args.cleos + 'push action eosio activate \'["299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707"]\' -p eosio@active')
|
||||
# CRYPTO_PRIMITIVES
|
||||
retry(args.cleos + 'push action eosio activate \'["6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc"]\' -p eosio@active')
|
||||
sleep(1)
|
||||
|
||||
# install eosio.system latest version
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace {
|
||||
}
|
||||
|
||||
template <typename SNAPSHOT_SUITE>
|
||||
void verify_integrity_hash(controller& lhs, controller& rhs) {
|
||||
void verify_integrity_hash(const controller& lhs, const controller& rhs) {
|
||||
const auto lhs_integrity_hash = lhs.calculate_integrity_hash();
|
||||
const auto rhs_integrity_hash = rhs.calculate_integrity_hash();
|
||||
if (std::is_same_v<SNAPSHOT_SUITE, variant_snapshot_suite> && lhs_integrity_hash.str() != rhs_integrity_hash.str()) {
|
||||
|
||||
Reference in New Issue
Block a user