Compare commits

..

32 Commits

Author SHA1 Message Date
Lin Huang 95077ed429 Bump Leap to release/3.1.5 2023-07-12 09:25:47 -04:00
Lin Huang 05e6cc8c18 Update eos-vm to release/3.x 2023-07-12 09:25:10 -04:00
Lin Huang 5caf5833ad A companion Leap changes for fixing WASM memory exhaustion 2023-07-12 09:18:25 -04:00
Peter Oschwald ed854f2bbd Merge pull request #1291 from AntelopeIO/pinned-builds-workflow-in-ci
[3.1] Pinned Builds manual dispatch workflow in CI
2023-06-22 11:38:59 -05:00
Peter Oschwald e3976b8dc1 Merge pull request #1310 from AntelopeIO/pinned_build_install_prefix_knob
[3.1] `CMAKE_INSTALL_PREFIX=/usr` for pinned builds in CI
2023-06-22 10:59:43 -05:00
Peter Oschwald 02c43ca656 Use enf-x86-beefy-long runner 2023-06-22 09:30:09 -05:00
Peter Oschwald 1ec98976b1 Try newly added self hosted runner for pinned builds. 2023-06-16 14:42:43 -05:00
Peter Oschwald 93833b8e03 Simplify naming and path matching for artifact. 2023-06-16 14:14:55 -05:00
Matt Witherspoon d6cd2c9a7d LEAP_PINNED_INSTALL_PREFIX knob to set pinned_build.sh CMAKE_INSTALL_PREFIX 2023-06-15 22:37:09 -04:00
Peter Oschwald ae2679e164 Cleanup. 2023-06-15 16:13:03 -05:00
Peter Oschwald 0f25eaa33a Remove quotes from path for upload. 2023-06-15 14:13:06 -05:00
Peter Oschwald b7b4554a18 Fix spelling causing issue with GITHUB_ENV. And trying again to get artifact name correctly. 2023-06-15 12:35:43 -05:00
Peter Oschwald 20e59a92bc Not finding deb packages. check dir structure some more. 2023-06-15 10:49:04 -05:00
Peter Oschwald 31fd1361aa Something is not matching up with expected dir or file structure. 2023-06-15 08:00:00 -05:00
Peter Oschwald 449f37133b Skip wildcards in upload-artifact and capture artifact name with regex grep and store in env variable. 2023-06-14 16:44:42 -05:00
Peter Oschwald feeee5eb8f Say yes. 2023-06-14 15:37:38 -05:00
Peter Oschwald 32de87b185 Update package lists first. 2023-06-14 15:35:28 -05:00
Peter Oschwald 78dd785035 Need software-properties-common and a apt-get update to get add-apt-repository to work. 2023-06-14 15:34:06 -05:00
Peter Oschwald f4b39ea29e Use single quotes. 2023-06-14 15:30:35 -05:00
Peter Oschwald 20f45e5923 Add conditional step to add updated apt repository for git.
Ubuntu 18.04 installs  git 2.17.1, but need 2.18+ for git submodules to work.
2023-06-14 15:27:18 -05:00
Peter Oschwald fc2166a46d Merge branch 'init-pinned-builds-workflow-in-ci' into pinned-builds-workflow-in-ci 2023-06-14 13:58:18 -05:00
Peter Oschwald 39a5ba846a Have to have a job for github. Add temp job. 2023-06-14 13:57:00 -05:00
Peter Oschwald e4b28a7854 Remove empty jobs section. 2023-06-14 13:54:13 -05:00
Peter Oschwald e4819c35e1 Merge branch 'init-pinned-builds-workflow-in-ci' into pinned-builds-workflow-in-ci 2023-06-14 13:51:11 -05:00
Peter Oschwald 7b7027cbee Not using cached build environments so removing this job. 2023-06-14 13:49:33 -05:00
Peter Oschwald 74fb1615d8 Add pinned to artifact name and don't upload dev artifact by filtering out in regex. 2023-06-14 13:02:32 -05:00
Peter Oschwald 5523010cfd Fix syntax and forgotten run command. 2023-06-14 13:00:00 -05:00
Peter Oschwald 7c106605cc Not using cached build environments so removing this job. 2023-06-14 12:16:11 -05:00
Peter Oschwald 9047d1175b For now run on github runner. 2023-06-14 12:05:12 -05:00
Peter Oschwald da6a068639 Script already runs cpack, remove. Break artifact check into own step for easier removal in future. 2023-06-14 12:03:27 -05:00
Peter Oschwald a886743005 Initial work to run pinned_build script on base images.
Build package and upload artifacts.
2023-06-14 11:44:53 -05:00
Peter Oschwald 0dbfb1a6ed Creating a shell of the initial pinned_build.yaml workflow to be merged quickly allowing development of actual workflow in follow on branch.
Need to have workflow file merged before github will allow triggering it in a development branch.
2023-06-14 11:26:08 -05:00
1510 changed files with 25367 additions and 90009 deletions
+2 -4
View File
@@ -10,17 +10,15 @@ RUN apt-get update && apt-get upgrade -y && \
libcurl4-openssl-dev \
libgmp-dev \
libssl-dev \
libusb-1.0-0-dev \
llvm-7-dev \
ninja-build \
pkg-config \
python3 \
python3-numpy \
python3-pip \
software-properties-common \
zlib1g-dev \
zstd
RUN python3 -m pip install dataclasses
# GitHub's actions/checkout requires git 2.18+ but Ubuntu 18 only provides 2.17
RUN add-apt-repository ppa:git-core/ppa && apt update && apt install -y git
+2 -1
View File
@@ -10,7 +10,8 @@ RUN apt-get update && apt-get upgrade -y && \
libcurl4-openssl-dev \
libgmp-dev \
libssl-dev \
libusb-1.0-0-dev \
llvm-11-dev \
ninja-build \
python3-numpy \
pkg-config \
zstd
+2 -1
View File
@@ -10,7 +10,8 @@ RUN apt-get update && apt-get upgrade -y && \
libcurl4-openssl-dev \
libgmp-dev \
libssl-dev \
libusb-1.0-0-dev \
llvm-11-dev \
ninja-build \
python3-numpy \
pkg-config \
zstd
@@ -1,14 +0,0 @@
name: 'Parallel ctest'
description: 'Runs a set of labeled ctests in parallel via multiple docker containers'
inputs:
container:
required: true
error-log-paths:
required: true
log-tarball-prefix:
required: true
tests-label:
required: true
runs:
using: 'node16'
main: 'dist/index.mjs'
File diff suppressed because one or more lines are too long
@@ -1,69 +0,0 @@
import child_process from 'node:child_process';
import process from 'node:process';
import stream from 'node:stream';
import fs from 'node:fs';
import zlib from 'node:zlib';
import tar from 'tar-stream';
import core from '@actions/core'
const container = core.getInput('container', {required: true});
const error_log_paths = JSON.parse(core.getInput('error-log-paths', {required: true}));
const log_tarball_prefix = core.getInput('log-tarball-prefix', {required: true});
const tests_label = core.getInput('tests-label', {required: true});
try {
if(child_process.spawnSync("docker", ["run", "--name", "base", "-v", `${process.cwd()}/build.tar.zst:/build.tar.zst`, "--workdir", "/__w/leap/leap", container, "sh", "-c", "zstdcat /build.tar.zst | tar x"], {stdio:"inherit"}).status)
throw new Error("Failed to create base container");
if(child_process.spawnSync("docker", ["commit", "base", "baseimage"], {stdio:"inherit"}).status)
throw new Error("Failed to create base image");
if(child_process.spawnSync("docker", ["rm", "base"], {stdio:"inherit"}).status)
throw new Error("Failed to remove base container");
// the correct approach is by far "--show-only=json-v1" and then pluck out .tests[].name; but that doesn't work on U18's cmake 3.10 since it lacks json-v1 output
const test_query_result = child_process.spawnSync("docker", ["run", "--rm", "baseimage", "bash", "-e", "-o", "pipefail", "-c", `cd build; ctest -L '${tests_label}' --show-only | head -n -1 | cut -d ':' -f 2 -s | jq -cnR '[inputs | select(length>0)[1:]]'`]);
if(test_query_result.status)
throw new Error("Failed to discover tests with label")
const tests = JSON.parse(test_query_result.stdout);
let subprocesses = [];
tests.forEach(t => {
subprocesses.push(new Promise(resolve => {
child_process.spawn("docker", ["run", "--security-opt", "seccomp=unconfined", "-e", "GITHUB_ACTIONS=True", "--name", t, "--init", "baseimage", "bash", "-c", `cd build; ctest --output-on-failure -R '^${t}$'`], {stdio:"inherit"}).on('close', code => resolve(code));
}));
});
const results = await Promise.all(subprocesses);
for(let i = 0; i < results.length; ++i) {
if(results[i] === 0)
continue;
//failing test
core.setFailed("Some tests failed");
let extractor = tar.extract();
let packer = tar.pack();
extractor.on('entry', (header, stream, next) => {
if(!header.name.startsWith(`__w/leap/leap/build`)) {
stream.on('end', () => next());
stream.resume();
return;
}
header.name = header.name.substring(`__w/leap/leap/`.length);
if(header.name !== "build/" && error_log_paths.filter(p => header.name.startsWith(p)).length === 0) {
stream.on('end', () => next());
stream.resume();
return;
}
stream.pipe(packer.entry(header, next));
}).on('finish', () => {packer.finalize()});
child_process.spawn("docker", ["export", tests[i]]).stdout.pipe(extractor);
stream.promises.pipeline(packer, zlib.createGzip(), fs.createWriteStream(`${log_tarball_prefix}-${tests[i]}-logs.tar.gz`));
}
} catch(e) {
core.setFailed(`Uncaught exception ${e.message}`);
}
@@ -1,351 +0,0 @@
{
"name": "parallel-ctest-containers",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"dependencies": {
"@actions/core": "^1.9.1",
"@vercel/ncc": "^0.34.0",
"tar-stream": "^2.2.0"
}
},
"node_modules/@actions/core": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"dependencies": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"node_modules/@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"dependencies": {
"tunnel": "^0.0.6"
}
},
"node_modules/@vercel/ncc": {
"version": "0.34.0",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
"bin": {
"ncc": "dist/ncc/cli.js"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dependencies": {
"once": "^1.4.0"
}
},
"node_modules/fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"engines": {
"node": ">=6"
}
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
},
"dependencies": {
"@actions/core": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"requires": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"requires": {
"tunnel": "^0.0.6"
}
},
"@vercel/ncc": {
"version": "0.34.0",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A=="
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"requires": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"requires": {
"once": "^1.4.0"
}
},
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"requires": {
"wrappy": "1"
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"requires": {
"safe-buffer": "~5.2.0"
}
},
"tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"requires": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
}
},
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
}
}
@@ -1,7 +0,0 @@
{
"dependencies": {
"@actions/core": "^1.9.1",
"@vercel/ncc": "^0.34.0",
"tar-stream": "^2.2.0"
}
}
+64 -71
View File
@@ -7,9 +7,13 @@ on:
- "release/*"
pull_request:
workflow_dispatch:
inputs:
run-lr-tests:
description: 'Run long running tests'
type: boolean
permissions:
packages: read
packages: write
contents: read
defaults:
@@ -40,9 +44,6 @@ jobs:
matrix:
platform: ${{fromJSON(needs.d.outputs.missing-platforms)}}
runs-on: ["self-hosted", "enf-x86-beefy"]
permissions:
packages: write
contents: read
steps:
- name: Login to Container Registry
uses: docker/login-action@v2
@@ -56,7 +57,6 @@ jobs:
push: true
tags: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
file: ${{fromJSON(needs.d.outputs.p)[matrix.platform].dockerfile}}
Build:
needs: [d, build-platforms]
if: always() && needs.d.result == 'success' && (needs.build-platforms.result == 'success' || needs.build-platforms.result == 'skipped')
@@ -64,6 +64,8 @@ jobs:
fail-fast: false
matrix:
platform: [ubuntu18, ubuntu20, ubuntu22]
outputs:
lr-tests: ${{steps.build.outputs.lr-tests}}
runs-on: ["self-hosted", "enf-x86-beefy"]
container: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
steps:
@@ -79,38 +81,25 @@ jobs:
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -GNinja ..
ninja
tar -pc -C .. --exclude "*.o" build | zstd --long -T0 -9 > ../build.tar.zst
# the correct approach is by far "--show-only=json-v1 | jq '.tests[].name' | jq -sc" but that doesn't work on U18's cmake 3.10 since it lacks json-v1
echo ::set-output name=lr-tests::$(ctest -L "long_running_tests" --show-only | head -n -1 | cut -d ':' -f 2 -s | jq -cnR '[inputs | select(length>0)[1:]]')
tar -pc -C .. --exclude "*.a" --exclude "*.o" build | zstd --long -T0 -9 > ../build.tar.gz
- name: Upload builddir
uses: AntelopeIO/upload-artifact-large-chunks-action@v1
uses: actions/upload-artifact@v3
with:
name: ${{matrix.platform}}-build
path: build.tar.zst
dev-package:
name: Build leap-dev package
needs: [d, Build]
if: always() && needs.Build.result == 'success'
runs-on: ubuntu-latest
container: ${{fromJSON(needs.d.outputs.p)['ubuntu20'].image}}
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Download builddir
uses: actions/download-artifact@v3
with:
name: ubuntu20-build
- name: Build dev package
run: |
zstdcat build.tar.zst | tar x
cd build
cpack
- name: Upload dev package
uses: actions/upload-artifact@v3
with:
name: leap-dev-ubuntu20-amd64
path: build/leap-dev*.deb
path: build.tar.gz
- name: Build dev package (Ubuntu 20 only)
if: matrix.platform == 'ubuntu20'
run: |
cd build
ninja package
- name: Upload dev package (Ubuntu 20 only)
if: matrix.platform == 'ubuntu20'
uses: actions/upload-artifact@v3
with:
name: leap-dev-ubuntu20-amd64
path: build/leap-dev*.deb
tests:
name: Tests
needs: [d, Build]
@@ -118,13 +107,13 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ubuntu20, ubuntu22]
runs-on: ["self-hosted", "enf-x86-hightier"]
container:
image: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
options: --security-opt seccomp=unconfined
platform: [ubuntu20]
runs-on: ["self-hosted", "enf-x86-beefy"]
container: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Download builddir
uses: actions/download-artifact@v3
with:
@@ -133,13 +122,9 @@ jobs:
run: |
# https://github.com/actions/runner/issues/2033 -- need this because of full version label test looking at git revs
chown -R $(id -u):$(id -g) $PWD
# jammy's boost 1.74 can stumble on an EXDEV via copy_file_range() it doesn't have a fallback for; re-eval once moving to std::filesystem
export TMPDIR="$PWD/tmp"
mkdir -p $TMPDIR
zstdcat build.tar.zst | tar x
zstdcat build.tar.gz | tar x
cd build
ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)"
np-tests:
name: NP Tests
needs: [d, Build]
@@ -147,62 +132,70 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ubuntu18, ubuntu20, ubuntu22]
runs-on: ["self-hosted", "enf-x86-midtier"]
platform: [ubuntu20]
runs-on: ubuntu-latest
container:
image: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
options: --init
steps:
- uses: actions/checkout@v3
- name: Download builddir
uses: actions/download-artifact@v3
with:
name: ${{matrix.platform}}-build
- name: Run tests in parallel containers
uses: ./.github/actions/parallel-ctest-containers
with:
container: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
error-log-paths: '["build/etc", "build/var", "build/leap-ignition-wd", "build/TestLogs"]'
log-tarball-prefix: ${{matrix.platform}}
tests-label: nonparallelizable_tests
- name: Run NP Tests
run: |
zstdcat build.tar.gz | tar x
cd build
ctest --output-on-failure -L "nonparallelizable_tests"
- name: Bundle logs from failed tests
if: failure()
run: tar --ignore-failed-read -czf ${{matrix.platform}}-serial-logs.tar.gz build/var build/etc build/leap-ignition-wd
- name: Upload logs from failed tests
uses: actions/upload-artifact@v3
if: failure()
with:
name: ${{matrix.platform}}-np-logs
path: '*-logs.tar.gz'
name: ${{matrix.platform}}-serial-logs
path: ${{matrix.platform}}-serial-logs.tar.gz
lr-tests:
name: LR Tests
needs: [d, Build]
if: always() && needs.Build.result == 'success'
if: always() && needs.Build.result == 'success' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/') || inputs.run-lr-tests)
strategy:
fail-fast: false
matrix:
platform: [ubuntu18, ubuntu20, ubuntu22]
runs-on: ["self-hosted", "enf-x86-lowtier"]
platform: [ubuntu20]
test-name: ${{fromJSON(needs.Build.outputs.lr-tests)}}
runs-on: ubuntu-latest
container:
image: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
options: --init
steps:
- uses: actions/checkout@v3
- name: Download builddir
uses: actions/download-artifact@v3
with:
name: ${{matrix.platform}}-build
- name: Run tests in parallel containers
uses: ./.github/actions/parallel-ctest-containers
with:
container: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
error-log-paths: '["build/etc", "build/var", "build/leap-ignition-wd", "build/TestLogs"]'
log-tarball-prefix: ${{matrix.platform}}
tests-label: long_running_tests
- name: Upload logs from failed tests
- name: Run ${{matrix.test-name}} Test
run: |
zstdcat build.tar.gz | tar x
cd build
ctest --output-on-failure -R ${{matrix.test-name}}
- name: Bundle logs from failed tests
if: failure()
run: tar --ignore-failed-read -czf ${{matrix.platform}}-${{matrix.test-name}}-logs.tar.gz build/var build/etc build/leap-ignition-wd
- name: Upload logs from failed tests
uses: actions/upload-artifact@v3
if: failure()
with:
name: ${{matrix.platform}}-lr-logs
path: '*-logs.tar.gz'
name: ${{matrix.platform}}-${{matrix.test-name}}-logs
path: ${{matrix.platform}}-${{matrix.test-name}}-logs.tar.gz
all-passing:
name: All Required Tests Passed
needs: [dev-package, tests, np-tests]
needs: [tests, np-tests]
if: always()
runs-on: ubuntu-latest
steps:
- if: needs.dev-package.result != 'success' || needs.tests.result != 'success' || needs.np-tests.result != 'success'
- if: needs.tests.result != 'success' || needs.np-tests.result != 'success'
run: false
-42
View File
@@ -1,42 +0,0 @@
name: Jira Issue Creator
on:
issues:
types:
- labeled
jobs:
create-jira-issue:
runs-on: ubuntu-latest
if: github.event.label.name == 'OCI'
steps:
- name: Create json issue file
run: |
cat << EOF > issue.json
{
"fields": {
"project":
{
"key": "$JIRA_PROJECT_KEY"
},
"summary": "$JIRA_ISSUE_SUMMARY",
"description": "$JIRA_ISSUE_DESCRIPTION",
"issuetype": {
"name": "$JIRA_ISSUE_TYPE_NAME"
}
}
}
EOF
env:
JIRA_PROJECT_KEY: ${{ secrets.JIRA_PROJECT_KEY }}
JIRA_ISSUE_SUMMARY: ${{ github.event.issue.title }}
JIRA_ISSUE_DESCRIPTION: "${{ github.event.issue.url }}\\n\\n${{ github.event.issue.html_url }}"
JIRA_ISSUE_TYPE_NAME: "Story"
- name: Check issue json
run: |
cat issue.json
- name: Trigger jira issue creation
run: |
curl -u $JIRA_AUTH -X POST --data @issue.json -H "Content-Type: application/json" --url $JIRA_PROJECT_URL
env:
JIRA_AUTH: ${{ secrets.JIRA_USN_AND_TOKEN }}
JIRA_PROJECT_URL: ${{ secrets.JIRA_PROJECT_URL }}
-18
View File
@@ -1,18 +0,0 @@
name: Label New Issue
on:
issues:
types: opened
jobs:
label_new_issue:
uses: AntelopeIO/issue-project-labeler-workflow/.github/workflows/issue-project-labeler.yaml@v1
with:
issue-id: ${{github.event.issue.node_id}}
label: triage
org-project: 'Team Backlog'
project-field: Status=Todo
skip-if-existing-project: true
secrets:
token: ${{secrets.ENFCIBOT_REPO_AND_PROJECTS}}
+58
View File
@@ -0,0 +1,58 @@
name: "Pinned Build"
on:
workflow_dispatch:
permissions:
packages: read
contents: read
defaults:
run:
shell: bash
jobs:
Build:
name: Build
strategy:
fail-fast: false
matrix:
platform: [ubuntu18, ubuntu20, ubuntu22]
runs-on: ["self-hosted", "enf-x86-beefy-long"]
container: ${{ matrix.platform == 'ubuntu18' && 'ubuntu:bionic' || matrix.platform == 'ubuntu20' && 'ubuntu:focal' || 'ubuntu:jammy' }}
steps:
- name: Conditionally update git repo
if: ${{ matrix.platform == 'ubuntu18' }}
run: |
apt-get update
apt-get install -y software-properties-common
apt-get update
add-apt-repository ppa:git-core/ppa
- name: Update and Install git
run: |
apt-get update
apt-get install -y git
git --version
- name: Clone leap
uses: actions/checkout@v3
with:
submodules: recursive
- name: Install dependencies
run: |
# https://github.com/actions/runner/issues/2033
chown -R $(id -u):$(id -g) $PWD
./scripts/install_deps.sh
- name: Build Pinned Build
env:
LEAP_PINNED_INSTALL_PREFIX: /usr
run: |
./scripts/pinned_build.sh deps build "$(nproc)"
- name: Upload package
uses: actions/upload-artifact@v3
with:
name: leap-${{matrix.platform}}-pinned-amd64
path: build/leap-3*.deb
- name: Run Parallel Tests
run: |
cd build
ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)" --timeout 420
+3 -4
View File
@@ -10,7 +10,6 @@
*.abi.hpp
*.cmake
!.cicd
!package.cmake
!CMakeModules/*.cmake
*.ninja
\#*
@@ -77,17 +76,17 @@ witness_node_data_dir
Testing/*
build.tar.gz
[Bb]uild*/*
build/*
build-debug/*
deps/*
dependencies/*
etc/eosio/node_*
TestLogs*
var/lib/node_*
.vscode
.idea/
*.iws
.DS_Store
CMakeLists.txt.user
!*.swagger.*
+9 -18
View File
@@ -7,27 +7,18 @@
[submodule "libraries/eos-vm"]
path = libraries/eos-vm
url = https://github.com/AntelopeIO/eos-vm
[submodule "libraries/fc"]
path = libraries/fc
url = https://github.com/AntelopeIO/fc
[submodule "libraries/softfloat"]
path = libraries/softfloat
url = https://github.com/AntelopeIO/berkeley-softfloat-3
[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
[submodule "libraries/libfc/include/fc/crypto/webauthn_json"]
path = libraries/libfc/include/fc/crypto/webauthn_json
url = https://github.com/Tencent/rapidjson/
[submodule "libraries/libfc/secp256k1/secp256k1"]
path = libraries/libfc/secp256k1/secp256k1
url = https://github.com/bitcoin-core/secp256k1
[submodule "libraries/prometheus/prometheus-cpp"]
path = libraries/prometheus/prometheus-cpp
url = https://github.com/jupp0r/prometheus-cpp.git
[submodule "libraries/libfc/libraries/bn256"]
path = libraries/libfc/libraries/bn256
url = https://github.com/AntelopeIO/bn256
[submodule "libraries/cli11/cli11"]
path = libraries/cli11/cli11
url = https://github.com/AntelopeIO/CLI11.git
[submodule "wasm-spec-tests"]
path = wasm-spec-tests
url = https://github.com/AntelopeIO/wasm-spec-tests
+44 -90
View File
@@ -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_MAJOR 3)
set(VERSION_MINOR 1)
set(VERSION_PATCH 0)
set(VERSION_SUFFIX dev)
set(VERSION_PATCH 5)
#set(VERSION_SUFFIX rc4)
if(VERSION_SUFFIX)
set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}")
@@ -24,16 +24,9 @@ else()
set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
endif()
# Options
option(ENABLE_WERROR "Enable `-Werror` compilation flag." Off)
option(ENABLE_WEXTRA "Enable `-Wextra` compilation flag." Off)
set( CLI_CLIENT_EXECUTABLE_NAME cleos )
set( NODE_EXECUTABLE_NAME nodeos )
set( KEY_STORE_EXECUTABLE_NAME keosd )
set( LEAP_UTIL_EXECUTABLE_NAME leap-util )
# http://stackoverflow.com/a/18369825
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
@@ -60,12 +53,10 @@ set(ENABLE_MULTIVERSION_PROTOCOL_TEST FALSE CACHE BOOL "Enable nodeos multiversi
# add defaults for openssl
if(APPLE AND UNIX AND "${OPENSSL_ROOT_DIR}" STREQUAL "")
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
set(OPENSSL_ROOT_DIR "/opt/homebrew/opt/openssl@3;/opt/homebrew/opt/openssl@1.1")
else()
set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl@3;/usr/local/opt/openssl@1.1")
endif()
set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl@3;/usr/local/opt/openssl@1.1")
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)
@@ -132,16 +123,6 @@ else()
endif()
endif()
if(ENABLE_WERROR)
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror" )
endif()
if(ENABLE_WEXTRA)
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra" )
endif()
option(EOSIO_ENABLE_DEVELOPER_OPTIONS "enable developer options for Leap" OFF)
# based on http://www.delorie.com/gnu/docs/gdb/gdb_70.html
@@ -196,10 +177,16 @@ add_subdirectory( scripts )
add_subdirectory( unittests )
add_subdirectory( tests )
add_subdirectory( tools )
add_subdirectory( benchmark )
option(DISABLE_WASM_SPEC_TESTS "disable building of wasm spec unit tests" OFF)
if (NOT DISABLE_WASM_SPEC_TESTS)
add_subdirectory( wasm-spec-tests/generated-tests )
endif()
install(FILES testnet.template DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/eosio/launcher COMPONENT dev EXCLUDE_FROM_ALL)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testnet.template ${CMAKE_CURRENT_BINARY_DIR}/etc/eosio/launcher/testnet.template COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/eosio.version.in ${CMAKE_CURRENT_BINARY_DIR}/eosio.version.hpp)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eosio.version.hpp DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR} COMPONENT dev EXCLUDE_FROM_ALL)
@@ -226,71 +213,35 @@ install(FILES ${CMAKE_BINARY_DIR}/modules/leap-config.cmake DESTINATION ${CMAKE_
install(FILES ${CMAKE_BINARY_DIR}/modules/EosioTester.cmake DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/leap COMPONENT dev EXCLUDE_FROM_ALL)
install(FILES ${CMAKE_SOURCE_DIR}/CMakeModules/EosioCheckVersion.cmake DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/leap COMPONENT dev EXCLUDE_FROM_ALL)
configure_file(LICENSE licenses/leap/LICENSE COPYONLY)
configure_file(libraries/softfloat/COPYING.txt licenses/leap/LICENSE.softfloat COPYONLY)
configure_file(libraries/wasm-jit/LICENSE licenses/leap/LICENSE.wavm COPYONLY)
configure_file(libraries/libfc/secp256k1/secp256k1/COPYING licenses/leap/LICENSE.secp256k1 COPYONLY)
configure_file(libraries/libfc/include/fc/crypto/webauthn_json/license.txt licenses/leap/LICENSE.rapidjson COPYONLY)
configure_file(libraries/eos-vm/LICENSE licenses/leap/LICENSE.eos-vm COPYONLY)
configure_file(libraries/prometheus/prometheus-cpp/LICENSE licenses/leap/LICENSE.prom COPYONLY)
configure_file(programs/cleos/LICENSE.CLI11 licenses/leap/LICENSE.CLI11 COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/LICENSE
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/libraries/softfloat/COPYING.txt
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.softfloat COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/libraries/wasm-jit/LICENSE
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.wavm COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/secp256k1/secp256k1/COPYING
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.secp256k1 COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/include/fc/crypto/webauthn_json/license.txt
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.rapidjson COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/src/network/LICENSE.go
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.go COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/libraries/yubihsm/LICENSE
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.yubihsm COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/libraries/eos-vm/LICENSE
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.eos-vm COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/programs/cleos/LICENSE.CLI11
${CMAKE_BINARY_DIR}/programs/cleos/LICENSE.CLI11 COPYONLY)
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/licenses/leap" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/" COMPONENT base)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libraries/testing/contracts DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/libraries/testing COMPONENT dev EXCLUDE_FROM_ALL
PATTERN "CMakeFiles" EXCLUDE
PATTERN "*.cmake" EXCLUDE
PATTERN "Makefile" EXCLUDE)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/unittests/contracts DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/unittests COMPONENT dev EXCLUDE_FROM_ALL
PATTERN "CMakeFiles" EXCLUDE
PATTERN "*.cmake" EXCLUDE
PATTERN "Makefile" EXCLUDE)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests/TestHarness DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/tests COMPONENT dev EXCLUDE_FROM_ALL
FILES_MATCHING
PATTERN "*.py"
PATTERN "*.json"
PATTERN "__pycache__" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tests/launcher.py DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/tests COMPONENT dev EXCLUDE_FROM_ALL)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21)
# Cmake versions < 3.21 did not support installing symbolic links to a directory via install(FILES ...)
# Cmake 3.21 fixed this (https://gitlab.kitware.com/cmake/cmake/-/commit/d71a7cc19d6e03f89581efdaa8d63db216184d40)
# If/when the lowest cmake version supported becomes >= 3.21, the else block as well as the postinit and prerm scripts
# would be a good option to remove in favor of using the facilities in cmake / cpack directly.
add_custom_target(link_target ALL
COMMAND ${CMAKE_COMMAND} -E make_directory lib/python3/dist-packages
COMMAND ${CMAKE_COMMAND} -E create_symlink ../../../share/leap_testing/tests/TestHarness lib/python3/dist-packages/TestHarness
COMMAND ${CMAKE_COMMAND} -E make_directory share/leap_testing
COMMAND ${CMAKE_COMMAND} -E create_symlink ../../bin share/leap_testing/bin)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/python3/dist-packages/TestHarness DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages COMPONENT dev EXCLUDE_FROM_ALL)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/leap_testing/bin DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing COMPONENT dev EXCLUDE_FROM_ALL)
else()
# The following install(CODE ...) steps are necessary for `make dev-install` to work on cmake versions < 3.21.
# However, it can flag as an error if using `make package` instead of `make dev-install` for installation.
# This is due to those directories and symbolic links being created in the postinit script during the package install instead.
# Note If/when doing `make package`, it is not a true error if you see:
# Error creating directory "/<leap_install_dir>/lib/python3/dist-packages".
# CMake Error: failed to create symbolic link '/<leap_install_dir>/lib/python3/dist-packages/TestHarness': no such file or directory
# CMake Error: failed to create symbolic link '/<leap_install_dir>/share/leap_testing/bin': no such file or directory
install(CODE "execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages)" COMPONENT dev EXCLUDE_FROM_ALL)
install(CODE "execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink ../../../share/leap_testing/tests/TestHarness ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages/TestHarness)" COMPONENT dev EXCLUDE_FROM_ALL)
install(CODE "execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink ../../bin ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/bin)" COMPONENT dev EXCLUDE_FROM_ALL)
# The `make package` installation of symlinks happens via the `postinst` script installed in cmake.package via the line below
endif()
configure_file(${CMAKE_SOURCE_DIR}/libraries/cli11/bash-completion/completions/leap-util
${CMAKE_BINARY_DIR}/programs/leap-util/bash-completion/completions/leap-util COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/libraries/cli11/bash-completion/completions/cleos
${CMAKE_BINARY_DIR}/programs/cleos/bash-completion/completions/cleos COPYONLY)
install(FILES libraries/cli11/bash-completion/completions/leap-util DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/bash-completion/completions COMPONENT base)
install(FILES libraries/cli11/bash-completion/completions/cleos DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/bash-completion/completions COMPONENT base)
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ COMPONENT base)
install(FILES libraries/softfloat/COPYING.txt DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.softfloat COMPONENT base)
install(FILES libraries/wasm-jit/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.wavm COMPONENT base)
install(FILES libraries/fc/secp256k1/secp256k1/COPYING DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.secp256k1 COMPONENT base)
install(FILES libraries/fc/include/fc/crypto/webauthn_json/license.txt DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.rapidjson COMPONENT base)
install(FILES libraries/fc/src/network/LICENSE.go DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ COMPONENT base)
install(FILES libraries/yubihsm/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.yubihsm COMPONENT base)
install(FILES libraries/eos-vm/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.eos-vm COMPONENT base)
install(FILES libraries/fc/libraries/ff/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.libff COMPONENT base)
install(FILES programs/cleos/LICENSE.CLI11 DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ COMPONENT base)
add_custom_target(dev-install
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}"
@@ -299,6 +250,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)
+10 -5
View File
@@ -54,10 +54,15 @@ find_package(Boost @Boost_MAJOR_VERSION@.@Boost_MINOR_VERSION@ EXACT REQUIRED CO
find_library(libtester eosio_testing @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
find_library(libchain eosio_chain @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
find_library(libfc fc @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
find_library(libsecp256k1 secp256k1 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
find_library(libbn256 bn256 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
if ( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" )
find_library(libfc fc_debug @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
find_library(libsecp256k1 secp256k1_debug @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
else()
find_library(libfc fc @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
find_library(libsecp256k1 secp256k1 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
endif()
find_library(libff ff @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
find_library(libwasm WASM @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
find_library(libwast WAST @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
find_library(libir IR @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
@@ -98,7 +103,7 @@ macro(add_eosio_test_executable test_name)
${libchainbase}
${libbuiltins}
${libsecp256k1}
${libbn256}
${libff}
@GMP_LIBRARY@
${Boost_FILESYSTEM_LIBRARY}
@@ -115,7 +120,7 @@ macro(add_eosio_test_executable test_name)
${WRAP_MAIN}
Threads::Threads
)
#adds -ltr. Ubuntu eosio.contracts build breaks without this
if(UNIX AND NOT APPLE)
target_link_libraries(${test_name} ${LIBRT})
+13 -7
View File
@@ -51,10 +51,16 @@ 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(libsecp256k1 secp256k1 @CMAKE_BINARY_DIR@/libraries/libfc/secp256k1 NO_DEFAULT_PATH)
find_library(libbn256 bn256 @CMAKE_BINARY_DIR@/libraries/libfc/libraries/bn256/src NO_DEFAULT_PATH)
if ( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" )
find_library(libfc fc_debug @CMAKE_BINARY_DIR@/libraries/fc NO_DEFAULT_PATH)
find_library(libsecp256k1 secp256k1_debug @CMAKE_BINARY_DIR@/libraries/fc/secp256k1 NO_DEFAULT_PATH)
else()
find_library(libfc fc @CMAKE_BINARY_DIR@/libraries/fc NO_DEFAULT_PATH)
find_library(libsecp256k1 secp256k1 @CMAKE_BINARY_DIR@/libraries/fc/secp256k1 NO_DEFAULT_PATH)
endif()
find_library(libff ff @CMAKE_BINARY_DIR@/libraries/fc/libraries/ff/libff NO_DEFAULT_PATH)
find_library(libwasm WASM @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WASM NO_DEFAULT_PATH)
find_library(libwast WAST @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WAST NO_DEFAULT_PATH)
find_library(libir IR @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/IR NO_DEFAULT_PATH)
@@ -95,7 +101,7 @@ macro(add_eosio_test_executable test_name)
${libchainbase}
${libbuiltins}
${libsecp256k1}
${libbn256}
${libff}
@GMP_LIBRARY@
${Boost_FILESYSTEM_LIBRARY}
@@ -112,7 +118,7 @@ macro(add_eosio_test_executable test_name)
${WRAP_MAIN}
Threads::Threads
)
#adds -ltr. Ubuntu eosio.contracts build breaks without this
if(UNIX AND NOT APPLE)
target_link_libraries(${test_name} ${LIBRT})
@@ -123,7 +129,7 @@ macro(add_eosio_test_executable test_name)
@OPENSSL_INCLUDE_DIR@
@CMAKE_SOURCE_DIR@/libraries/chain/include
@CMAKE_BINARY_DIR@/libraries/chain/include
@CMAKE_SOURCE_DIR@/libraries/libfc/include
@CMAKE_SOURCE_DIR@/libraries/fc/include
@CMAKE_SOURCE_DIR@/libraries/softfloat/source/include
@CMAKE_SOURCE_DIR@/libraries/appbase/include
@CMAKE_SOURCE_DIR@/libraries/chainbase/include
@@ -170,7 +176,7 @@ if(ENABLE_COVERAGE_TESTING)
COMMAND ${LCOV_PATH} --directory . --capture --gcov-tool ${CMAKE_SOURCE_DIR}/tools/llvm-gcov.sh --output-file ${Coverage_NAME}.info
COMMAND ${LCOV_PATH} -remove ${Coverage_NAME}.info '*/boost/*' '/usr/lib/*' '/usr/include/*' '*/externals/*' '*/libfc/*' '*/wasm-jit/*' --output-file ${Coverage_NAME}_filtered.info
COMMAND ${LCOV_PATH} -remove ${Coverage_NAME}.info '*/boost/*' '/usr/lib/*' '/usr/include/*' '*/externals/*' '*/fc/*' '*/wasm-jit/*' --output-file ${Coverage_NAME}_filtered.info
COMMAND ${GENHTML_PATH} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info
+12 -15
View File
@@ -50,12 +50,12 @@ Requirements to build:
- LLVM 7 - 11 - for Linux only
- newer versions do not work
- openssl 1.1+
- libcurl
- curl
- libcurl 7.40.0+
- libusb
- git
- GMP
- Python 3
- python3-numpy
- zlib
### Step 1 - Clone
@@ -111,14 +111,12 @@ Make sure you are in the root of the `leap` repo, then run the `install_depts.sh
sudo scripts/install_deps.sh
```
Next, run the pinned build script. You have to give it three arguments in the following order:
1. A temporary folder, for all dependencies that need to be built from source.
1. A build folder, where the binaries you need to install will be built to.
1. The number of jobs or CPU cores/threads to use (note the [jobs flag](#step-3---build) warning above).
Next, run the pinned build script. You have to give it three arguments, in the following order:
- A temporary folder, for all dependencies that need to be built from source.
- A build folder, where the binaries you need to install will be built to.
- The number of jobs or CPU cores/threads to use (note the [jobs flag](#step-3---build) warning above).
> 🔒 You do not need to run this script with `sudo` or as root.
For example, the following command runs the `pinned_build.sh` script, specifies a `deps` and `build` folder in the root of the Leap repo for the first two arguments, then builds the packages using all of your computer's CPU threads:
The following command runs the `pinned_build.sh` script, specifies a `deps` and `build` folder in the root of the Leap repo for the first two arguments, then builds the packages using all of your computer's CPU threads (Note: you don't need `sudo` for this command):
```bash
scripts/pinned_build.sh deps build "$(nproc)"
```
@@ -141,15 +139,16 @@ sudo apt-get install -y \
libcurl4-openssl-dev \
libgmp-dev \
libssl-dev \
libusb-1.0-0-dev \
llvm-11-dev \
python3-numpy
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>
@@ -167,13 +166,11 @@ sudo apt-get install -y \
libcurl4-openssl-dev \
libgmp-dev \
libssl-dev \
libusb-1.0-0-dev \
llvm-7-dev \
pkg-config \
python3 \
python3-numpy \
python3-pip \
zlib1g-dev
python3 -m pip install dataclasses
```
You need to build Boost from source on this distribution:
```bash
-7
View File
@@ -1,7 +0,0 @@
file(GLOB BENCHMARK "*.cpp")
add_executable( benchmark ${BENCHMARK} )
target_link_libraries( benchmark fc Boost::program_options bn256)
target_include_directories( benchmark PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}"
)
-112
View File
@@ -1,112 +0,0 @@
#include <iostream>
#include <bn256/bn256.h>
#include <benchmark.hpp>
namespace benchmark {
using bytes = std::vector<char>;
using g1g2_pair = std::vector<std::string>;
void add_benchmarking() {
const unsigned char point1[64] = {
12,175,215,144,98,95,151,228,179,85,31,170,172,159,40,255,250,252,68,28,235,65,172,180,69,164,153,29,187,239,220,201, // x
18,102,219,76,79,148,120,28,39,149,42,172,41,248,120,249,255,69,42,51,160,239,13,219,239,183,77,174,217,158,130,10,}; // y
const unsigned char point2[64] = {
12,144,10,32,104,85,103,36,222,232,48,152,108,217,40,145,230,48,8,54,0,7,134,164,7,10,139,110,95,205,124,121, // x
22,254,176,251,18,168,78,220,142,100,102,113,58,176,83,186,212,62,154,138,235,135,34,46,237,117,54,36,198,40,79,73,}; // y
unsigned char ans[64] ={};
auto f = [&]() {
auto res = bn256::g1_add(point1, point2, ans);
if (res == -1) {
std::cout << "alt_bn128_add failed" << std::endl;
}
};
benchmarking("alt_bn128_add", f);
}
void mul_benchmarking() {
const unsigned char point[64] = {
12,175,215,144,98,95,151,228,179,85,31,170,172,159,40,255,250,252,68,28,235,65,172,180,69,164,153,29,187,239,220,201, // x
18,102,219,76,79,148,120,28,39,149,42,172,41,248,120,249,255,69,42,51,160,239,13,219,239,183,77,174,217,158,130,10,}; // y
const unsigned char scalar[32] = {
25,62,182,170,104,140,135,90,37,150,0,77,2,77,146,71,54,101,113,69,177,216,157,4,229,213,33,215,169,99,150,91, }; // scaler size 256 bits
unsigned char ans[64] = {};
auto f = [&]() {
auto res = bn256::g1_scalar_mul(point, scalar, ans);
if (res == -1) {
std::cout << "alt_bn128_mul failed" << std::endl;
}
};
benchmarking("alt_bn128_mul", f);
}
void pair_benchmarking() {
const unsigned char g1_g2_pairs[] = {
/* pair 1 */
12,175,215,144,98,95,151,228,179,85,31,170,172,159,40,255,250,252,68,28,235,65,172,180,69,164,153,29,187,239,220,201,18,102,219,76,79,148,120,28,39,149,42,172,41,248,120,249,255,69,42,51,160,239,13,219,239,183,77,174,217,158,130,10,
46,24,234,176,148,82,198,136,44,30,157,18,217,25,49,241,63,197,2,151,14,150,136,210,114,4,74,124,145,225,131,139,13,60,0,50,236,103,39,15,150,226,246,189,209,113,0,46,151,39,41,6,87,119,228,213,45,225,29,234,161,110,43,87,3,237,74,227,93,23,171,129,49,118,228,173,154,111,168,220,161,46,140,103,155,56,168,207,254,90,228,76,188,232,25,34,44,102,159,35,193,216,177,31,131,247,226,19,170,222,26,227,86,37,81,149,202,144,188,126,120,168,9,195,32,169,147,161,
/* pair,2,*/
12,144,10,32,104,85,103,36,222,232,48,152,108,217,40,145,230,48,8,54,0,7,134,164,7,10,139,110,95,205,124,121,22,254,176,251,18,168,78,220,142,100,102,113,58,176,83,186,212,62,154,138,235,135,34,46,237,117,54,36,198,40,79,73,
0,186,148,242,227,252,208,242,165,128,1,160,59,2,6,195,30,54,69,118,8,28,223,92,254,98,110,219,90,92,7,113,26,8,119,98,122,61,119,91,216,107,29,179,122,218,203,6,84,109,119,140,44,12,57,157,203,90,14,108,218,54,94,44,42,77,118,169,232,192,189,60,129,213,156,157,215,160,91,214,138,130,119,145,167,89,237,149,225,85,151,33,89,181,224,235,2,91,213,225,37,226,214,14,255,84,254,117,142,211,28,164,78,254,64,11,126,217,25,124,203,220,52,181,39,32,78,132,
/* pair 3 */
48,58,116,183,56,3,62,111,104,127,0,7,202,204,146,2,236,192,214,213,231,100,12,17,104,47,76,49,149,39,35,179,2,162,218,104,52,130,61,134,223,111,123,225,186,122,171,2,144,236,110,29,26,142,113,183,238,44,130,30,76,212,52,15,
19,206,16,79,220,158,153,194,12,48,10,79,173,10,97,199,113,25,255,87,220,3,102,235,164,170,50,240,177,237,223,205,11,75,211,28,143,229,192,35,171,167,172,238,138,235,82,134,111,165,144,29,118,150,179,21,158,9,202,2,242,109,33,148,14,188,33,145,213,186,0,126,178,10,131,168,121,66,121,193,106,209,176,34,176,41,145,227,3,55,245,150,82,218,232,155,31,153,213,183,157,2,159,247,25,69,49,215,219,36,46,5,192,205,201,182,72,189,84,62,61,47,136,81,51,65,231,161,
/* pair 4 */
27,31,150,92,17,82,135,210,46,161,0,24,16,199,200,165,29,165,157,168,222,9,83,17,44,27,64,226,208,112,223,128,20,253,182,130,45,130,249,9,168,206,153,86,197,214,59,248,241,191,93,113,70,113,247,244,43,214,240,246,24,38,33,50,
23,76,241,195,191,99,69,237,123,173,212,42,74,85,138,108,39,80,105,135,226,11,84,237,39,73,180,224,42,230,246,76,26,61,86,57,253,213,223,2,93,42,38,186,38,38,206,38,209,138,153,181,57,89,16,187,234,2,110,23,12,14,252,240,32,231,237,147,16,62,220,6,160,64,154,167,57,238,243,112,255,35,80,36,100,173,21,58,96,244,77,245,75,202,24,63,35,178,46,215,219,69,120,221,70,119,111,195,145,45,109,84,206,76,254,205,98,167,30,72,117,5,128,129,156,128,196,192,
/* pair 5 */
33,230,106,254,43,77,114,126,9,205,25,63,9,170,62,237,149,102,198,184,60,31,185,213,103,120,71,249,28,106,238,107,1,133,60,180,58,152,18,177,142,248,46,186,90,34,94,200,235,158,242,255,209,32,143,133,102,195,19,107,153,42,207,228,
30,43,165,137,133,231,242,156,65,126,94,159,26,27,78,164,165,159,225,150,220,158,247,118,118,170,195,122,12,125,8,34,39,57,159,231,167,233,3,47,243,142,174,224,162,38,147,65,74,191,98,144,126,125,81,177,75,140,161,27,34,97,46,249,8,65,220,15,139,144,78,12,72,239,54,163,39,6,30,147,154,208,89,111,170,126,6,214,32,181,195,140,215,53,218,239,44,43,229,0,169,242,16,227,163,185,224,21,142,203,135,66,60,53,91,80,48,112,8,13,226,206,58,249,163,52,196,53,
/* pair 6 */
14,157,100,136,255,206,130,101,56,187,235,39,67,209,67,124,40,174,153,135,155,26,166,170,118,193,244,21,70,71,120,150,3,189,254,120,183,98,23,175,175,28,195,233,165,224,35,95,247,132,40,64,26,208,70,206,247,92,134,105,118,181,21,242,
16,159,200,208,93,99,234,139,8,222,239,67,3,187,15,125,5,144,190,196,146,171,15,218,92,36,37,130,2,201,241,182,36,31,104,164,95,29,73,231,87,50,174,142,209,72,31,75,48,13,70,237,118,193,39,85,97,88,228,50,77,163,209,112,7,202,214,212,235,15,224,247,229,179,101,15,72,130,125,8,62,227,46,20,109,53,26,168,10,237,222,85,169,133,181,196,25,36,112,182,41,208,39,132,100,181,199,189,44,99,238,140,6,187,19,197,99,93,243,63,159,132,211,0,230,118,153,54,
/* pair 7 */
31,60,154,8,188,169,224,107,69,183,223,15,60,32,61,51,81,226,85,38,72,88,241,202,216,204,253,98,0,250,116,167,21,255,0,81,80,3,108,196,240,102,114,33,33,122,116,155,188,19,232,217,42,217,54,195,91,187,88,188,249,218,240,146,
12,28,171,60,8,166,151,19,125,237,128,127,207,183,19,1,188,189,105,181,170,172,8,180,30,175,4,108,191,252,197,161,37,122,14,151,117,34,172,227,236,154,84,99,189,197,91,46,43,148,174,218,83,61,196,48,131,45,242,61,92,242,56,251,39,125,111,11,24,37,76,62,151,59,183,3,156,187,249,232,229,56,230,171,55,2,246,70,74,102,0,156,185,237,126,90,0,30,248,164,199,146,66,237,158,134,139,168,128,189,126,55,35,198,48,18,112,40,63,70,254,246,88,111,254,67,213,223,
/* pair 8 */
27,106,52,232,120,148,201,234,161,123,171,160,223,151,6,105,206,47,94,147,47,22,27,21,248,20,223,51,116,192,29,221,25,149,109,33,131,198,32,101,157,94,62,164,205,151,23,108,214,43,231,7,95,228,183,1,242,205,19,62,124,79,48,203,
37,186,150,204,63,241,145,219,169,250,247,76,247,18,135,175,140,58,209,133,113,144,185,191,101,197,252,253,50,126,188,177,45,103,105,194,21,229,145,210,89,135,244,248,238,64,102,155,129,232,252,32,208,82,51,131,113,100,25,174,253,19,211,18,6,77,66,232,173,42,146,120,106,72,92,144,51,233,117,184,113,60,33,118,209,83,119,93,170,253,126,41,58,13,85,111,30,233,117,238,183,18,219,38,216,163,244,98,219,254,156,189,57,246,220,178,17,190,88,84,13,41,8,236,181,155,85,198,
/* pair 9 */
25,62,182,170,104,140,135,90,37,150,0,77,2,77,146,71,54,101,113,69,177,216,157,4,229,213,33,215,169,99,150,91,5,185,157,10,152,12,220,171,39,188,1,48,87,129,192,101,36,179,99,212,123,207,13,76,89,78,8,154,75,239,117,189,
19,87,226,242,101,183,176,42,195,135,40,225,195,207,13,62,60,37,28,251,13,165,96,198,173,250,251,107,25,141,77,68,45,115,128,233,135,104,231,12,192,206,60,249,137,191,114,141,3,235,34,189,208,170,23,59,231,12,197,116,5,188,52,20,11,153,186,15,96,240,54,123,212,242,168,141,151,187,17,38,185,238,196,242,26,194,193,18,34,107,95,238,108,154,140,224,13,76,71,149,81,56,85,83,56,59,203,183,170,10,167,200,128,135,105,19,93,203,131,146,116,209,62,27,81,80,234,172,
/* pair 10 */
30,204,212,77,212,159,135,173,195,194,165,112,62,248,180,204,66,73,253,99,65,111,39,171,19,211,171,203,35,66,146,20,33,241,46,6,167,133,80,76,238,165,59,232,120,58,211,157,50,212,86,191,95,6,134,164,36,227,79,58,119,98,108,171,
48,49,12,141,166,151,158,56,136,255,197,138,114,195,39,59,71,236,82,57,149,249,170,55,187,95,193,171,14,124,45,87,7,157,47,178,153,237,194,157,142,194,100,14,40,51,61,201,244,93,61,196,154,59,14,135,209,72,102,186,14,228,228,152,40,246,109,82,93,249,92,105,191,121,77,108,20,87,3,87,167,173,171,255,189,34,155,239,218,95,181,153,222,20,120,195,27,28,47,82,113,3,218,129,54,210,185,165,206,99,126,61,217,19,237,5,12,90,148,246,128,231,63,53,37,223,204,195
};
// benchmarking 1 pair of points
auto f_1_pair = [&]() {
auto res = bn256::pairing_check({ g1_g2_pairs, 384}, [](){});
if (res == -1) {
std::cout << "alt_bn128_pair 1 pair failed" << std::endl;
}
};
benchmarking("alt_bn128_pair (1 pair)", f_1_pair);
// benchmarking 10 pair of points
auto f_10_pairs = [&]() {
auto res = bn256::pairing_check(g1_g2_pairs, [](){});
if (res == -1) {
std::cout << "alt_bn128_pair 10 pair failed" << std::endl;
}
};
benchmarking("alt_bn128_pair (10 pairs)", f_10_pairs);
}
void alt_bn_128_benchmarking() {
add_benchmarking();
mul_benchmarking();
pair_benchmarking();
}
} // benchmark
-82
View File
@@ -1,82 +0,0 @@
#include <chrono>
#include <iostream>
#include <iomanip>
#include <locale>
#include <benchmark.hpp>
namespace benchmark {
// update this map when a new feature is supported
// key is the name and value is the function doing benchmarking
std::map<std::string, std::function<void()>> features {
{ "alt_bn_128", alt_bn_128_benchmarking },
{ "modexp", modexp_benchmarking },
{ "key", key_benchmarking },
{ "hash", hash_benchmarking },
{ "blake2", blake2_benchmarking },
};
// values to control cout format
constexpr auto name_width = 28;
constexpr auto runs_width = 5;
constexpr auto time_width = 12;
constexpr auto ns_width = 2;
uint32_t num_runs = 1;
std::map<std::string, std::function<void()>> get_features() {
return features;
}
void set_num_runs(uint32_t runs) {
num_runs = runs;
}
void print_header() {
std::cout << std::left << std::setw(name_width) << "function"
<< std::setw(runs_width) << "runs"
<< std::setw(time_width + ns_width) << std::right << "average"
<< std::setw(time_width + ns_width) << "minimum"
<< std::setw(time_width + ns_width) << "maximum"
<< std::endl << std::endl;
}
void print_results(std::string name, uint32_t runs, uint64_t total, uint64_t min, uint64_t max) {
std::cout.imbue(std::locale(""));
std::cout
<< std::setw(name_width) << std::left << name
<< std::setw(runs_width) << runs
// std::fixed for not printing 1234 in 1.234e3.
// setprecision(0) for not printing fractions
<< std::right << std::fixed << std::setprecision(0)
<< std::setw(time_width) << total/runs << std::setw(ns_width) << " ns"
<< std::setw(time_width) << min << std::setw(ns_width) << " ns"
<< std::setw(time_width) << max << std::setw(ns_width) << " ns"
<< std::endl;
}
bytes to_bytes(const std::string& source) {
bytes output(source.length()/2);
fc::from_hex(source, output.data(), output.size());
return output;
};
void benchmarking(std::string name, const std::function<void()>& func) {
uint64_t total {0}, min {std::numeric_limits<uint64_t>::max()}, max {0};
for (auto i = 0U; i < num_runs; ++i) {
auto start_time = std::chrono::high_resolution_clock::now();
func();
auto end_time = std::chrono::high_resolution_clock::now();
uint64_t duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count();
total += duration;
min = std::min(min, duration);
max = std::max(max, duration);
}
print_results(name, num_runs, total, min, max);
}
} // benchmark
-25
View File
@@ -1,25 +0,0 @@
#pragma once
#include <functional>
#include <map>
#include <vector>
#include <fc/crypto/hex.hpp>
namespace benchmark {
using bytes = std::vector<char>;
void set_num_runs(uint32_t runs);
std::map<std::string, std::function<void()>> get_features();
void print_header();
bytes to_bytes(const std::string& source);
void alt_bn_128_benchmarking();
void modexp_benchmarking();
void key_benchmarking();
void hash_benchmarking();
void blake2_benchmarking();
void benchmarking(std::string name, const std::function<void()>& func);
} // benchmark
-21
View File
@@ -1,21 +0,0 @@
#include <fc/crypto/blake2.hpp>
#include <benchmark.hpp>
namespace benchmark {
void blake2_benchmarking() {
uint32_t _rounds = 0x0C;
bytes _h = to_bytes( "48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b");
bytes _m = to_bytes("6162630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
bytes _t0_offset = to_bytes("0300000000000000");
bytes _t1_offset = to_bytes("0000000000000000");
bool _f = false;
auto blake2_f = [&]() {
fc::blake2b(_rounds, _h, _m, _t0_offset, _t1_offset, _f, [](){});;
};
benchmarking("blake2", blake2_f);
}
} // benchmark
-89
View File
@@ -1,89 +0,0 @@
#include <fc/crypto/hex.hpp>
#include <fc/crypto/sha1.hpp>
#include <fc/crypto/sha3.hpp>
#include <fc/crypto/sha256.hpp>
#include <fc/crypto/sha512.hpp>
#include <fc/crypto/ripemd160.hpp>
#include <fc/utility.hpp>
#include <benchmark.hpp>
using namespace fc;
namespace benchmark {
void hash_benchmarking() {
std::string small_message = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ01";
// build a large message
constexpr auto large_msg_size = 4096;
std::string large_message;
large_message.reserve(large_msg_size);
uint32_t num_concats = large_msg_size/small_message.length();
for (uint32_t i = 0; i < num_concats; ++i) {
large_message += small_message;
}
auto sha1_small_msg = [&]() {
fc::sha1::hash(small_message);
};
benchmarking("sha1 (" + std::to_string(small_message.length()) + " bytes)", sha1_small_msg);
auto sha1_large_msg = [&]() {
fc::sha1::hash(large_message);
};
benchmarking("sha1 (" + std::to_string(large_message.length()) + " bytes)", sha1_large_msg);
auto sha256_small_msg = [&]() {
fc::sha256::hash(small_message);
};
benchmarking("sha256 (" + std::to_string(small_message.length()) + " bytes)", sha256_small_msg);
auto sha256_large_msg = [&]() {
fc::sha256::hash(large_message);
};
benchmarking("sha256 (" + std::to_string(large_message.length()) + " bytes)", sha256_large_msg);
auto sha512_small_msg = [&]() {
fc::sha512::hash(small_message);
};
benchmarking("sha512 (" + std::to_string(small_message.length()) + " bytes)", sha512_small_msg);
auto sha512_large_msg = [&]() {
fc::sha512::hash(large_message);
};
benchmarking("sha512 (" + std::to_string(large_message.length()) + " bytes)", sha512_large_msg);
auto ripemd160_small_msg = [&]() {
fc::ripemd160::hash(small_message);
};
benchmarking("ripemd160 (" + std::to_string(small_message.length()) + " bytes)", ripemd160_small_msg);
auto ripemd160_large_msg = [&]() {
fc::ripemd160::hash(large_message);
};
benchmarking("ripemd160 (" + std::to_string(large_message.length()) + " bytes)", ripemd160_large_msg);
auto sha3_small_msg = [&]() {
fc::sha3::hash(small_message, true);
};
benchmarking("sha3-256 (" + std::to_string(small_message.length()) + " bytes)", sha3_small_msg);
auto sha3_large_msg = [&]() {
fc::sha3::hash(large_message, true);
};
benchmarking("sha3-256 (" + std::to_string(large_message.length()) + " bytes)", sha3_large_msg);
auto keccak_small_msg = [&]() {
fc::sha3::hash(small_message, false);
};
benchmarking("keccak256 (" + std::to_string(small_message.length()) + " bytes)", keccak_small_msg);
auto keccak_large_msg = [&]() {
fc::sha3::hash(large_message, false);
};
benchmarking("keccak256 (" + std::to_string(large_message.length()) + " bytes)", keccak_large_msg);
}
} // benchmark
-109
View File
@@ -1,109 +0,0 @@
#include <fc/crypto/public_key.hpp>
#include <fc/crypto/private_key.hpp>
#include <fc/crypto/signature.hpp>
#include <fc/crypto/k1_recover.hpp>
#include <benchmark.hpp>
using namespace fc::crypto;
using namespace fc;
using namespace std::literals;
namespace benchmark {
void k1_sign_benchmarking() {
auto payload = "Test Cases";
auto digest = sha256::hash(payload, const_strlen(payload));
auto private_key_string = std::string("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3");
auto key = private_key(private_key_string);
auto sign_non_canonical_f = [&]() {
key.sign(digest, false);
};
benchmarking("k1_sign_non_canonical", sign_non_canonical_f);
}
void k1_recover_benchmarking() {
auto signature = to_bytes( "1b323dd47a1dd5592c296ee2ee12e0af38974087a475e99098a440284f19c1f7642fa0baa10a8a3ab800dfdbe987dee68a09b6fa3db45a5cc4f3a5835a1671d4dd");
auto digest = to_bytes( "92390316873c5a9d520b28aba61e7a8f00025ac069acd9c4d2a71d775a55fa5f");
auto recover_f = [&]() {
fc::k1_recover(signature, digest);
};
benchmarking("k1_recover", recover_f);
}
void k1_benchmarking() {
k1_sign_benchmarking();
k1_recover_benchmarking();
}
void r1_benchmarking() {
auto payload = "Test Cases";
auto digest = sha256::hash(payload, const_strlen(payload));
auto key = private_key::generate<r1::private_key_shim>();
auto sign_f = [&]() {
key.sign(digest);
};
benchmarking("r1_sign", sign_f);
auto sig = key.sign(digest);
auto recover_f = [&]() {
public_key(sig, digest);;
};
benchmarking("r1_recover", recover_f);
}
static fc::crypto::webauthn::signature make_webauthn_sig(const fc::crypto::r1::private_key& priv_key,
std::vector<uint8_t>& auth_data,
const std::string& json) {
//webauthn signature is sha256(auth_data || client_data_hash)
fc::sha256 client_data_hash = fc::sha256::hash(json);
fc::sha256::encoder e;
e.write((char*)auth_data.data(), auth_data.size());
e.write(client_data_hash.data(), client_data_hash.data_size());
r1::compact_signature sig = priv_key.sign_compact(e.result());
char buff[8192];
datastream<char*> ds(buff, sizeof(buff));
fc::raw::pack(ds, sig);
fc::raw::pack(ds, auth_data);
fc::raw::pack(ds, json);
ds.seekp(0);
fc::crypto::webauthn::signature ret;
fc::raw::unpack(ds, ret);
return ret;
}
void wa_benchmarking() {
static const r1::private_key priv = fc::crypto::r1::private_key::generate();
static const fc::sha256 d = fc::sha256::hash("sup"s);
static const fc::sha256 origin_hash = fc::sha256::hash("fctesting.invalid"s);
std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\", \"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
std::vector<uint8_t> auth_data(37);
memcpy(auth_data.data(), origin_hash.data(), sizeof(origin_hash));
auto sign = [&]() {
make_webauthn_sig(priv, auth_data, json);
};
benchmarking("webauthn_sign", sign);
auto sig = make_webauthn_sig(priv, auth_data, json);
auto recover= [&]() {
sig.recover(d, true);
};
benchmarking("webauthn_recover", recover);
}
void key_benchmarking() {
k1_benchmarking();
r1_benchmarking();
wa_benchmarking();
}
} // benchmark
-80
View File
@@ -1,80 +0,0 @@
#include <iostream>
#include <boost/program_options.hpp>
#include <benchmark.hpp>
namespace bpo = boost::program_options;
using bpo::options_description;
using bpo::variables_map;
int main(int argc, char* argv[]) {
uint32_t num_runs = 1;
std::string feature_name;
auto features = benchmark::get_features();
options_description cli ("benchmark command line options");
cli.add_options()
("feature,f", bpo::value<std::string>(), "feature to be benchmarked; if this option is not present, all features are benchmarked.")
("list,l", "list of supported features")
("runs,r", bpo::value<uint32_t>(&num_runs)->default_value(1000), "the number of times running a function during benchmarking")
("help,h", "benchmark functions, and report average, minimum, and maximum execution time in nanoseconds");
variables_map vmap;
try {
bpo::store(bpo::parse_command_line(argc, argv, cli), vmap);
bpo::notify(vmap);
if (vmap.count("help") > 0) {
cli.print(std::cerr);
return 0;
}
if (vmap.count("list") > 0) {
auto first = true;
std::cout << "Supported features are ";
for (auto& [name, f]: features) {
if (first) {
first = false;
} else {
std::cout << ", ";
}
std::cout << name;
}
std::cout << std::endl;
return 0;
}
if (vmap.count("feature") > 0) {
feature_name = vmap["feature"].as<std::string>();
if (features.find(feature_name) == features.end()) {
std::cout << feature_name << " is not supported" << std::endl;
return 1;
}
}
} catch (bpo::unknown_option &ex) {
std::cerr << ex.what() << std::endl;
cli.print (std::cerr);
return 1;
} catch( ... ) {
std::cerr << "unknown exception" << std::endl;
}
benchmark::set_num_runs(num_runs);
benchmark::print_header();
if (feature_name.empty()) {
for (auto& [name, f]: features) {
std::cout << name << ":" << std::endl;
f();
std::cout << std::endl;
}
} else {
std::cout << feature_name << ":" << std::endl;
features[feature_name]();
std::cout << std::endl;
}
return 0;
}
-58
View File
@@ -1,58 +0,0 @@
#include <fc/crypto/modular_arithmetic.hpp>
#include <random>
#include <benchmark.hpp>
namespace benchmark {
void modexp_benchmarking() {
std::mt19937 r(0x11223344);
auto generate_random_bytes = [](std::mt19937& rand_eng, unsigned int num_bytes) {
std::vector<char> result(num_bytes);
uint_fast32_t v = 0;
for(int byte_pos = 0, end = result.size(); byte_pos < end; ++byte_pos) {
if ((byte_pos & 0x03) == 0) { // if divisible by 4
v = rand_eng();
}
result[byte_pos] = v & 0xFF;
v >>= 8;
}
return result;
};
static constexpr unsigned int start_num_bytes = 128; // 64
static constexpr unsigned int end_num_bytes = 256; // 512
static constexpr unsigned int delta_num_bytes = 128; // 64
static_assert(start_num_bytes <= end_num_bytes);
static_assert(delta_num_bytes > 0);
static_assert((end_num_bytes - start_num_bytes) % delta_num_bytes == 0);
for (unsigned int n = start_num_bytes, slot = 0; n <= end_num_bytes; n += delta_num_bytes, ++slot) {
auto base = generate_random_bytes(r, n);
auto exponent = generate_random_bytes(r, n);
auto modulus = generate_random_bytes(r, n);
auto f = [&]() {
fc::modexp(base, exponent, modulus);
};
benchmarking(std::to_string(n*8) + " bit width", f);
}
// Running the above benchmark (using commented values for num_trials and *_num_bytes) with a release build on an AMD 3.4 GHz CPU
// provides average durations for executing mod_exp for increasing bit sizes for the value.
// For example: with 512-bit values, the average duration is approximately 40 microseconds; with 1024-bit values, the average duration
// is approximately 260 microseconds; with 2048-bit values, the average duration is approximately 2 milliseconds; and, with 4096-bit
// values, the average duration is approximately 14 milliseconds.
// It appears that a model of the average time that scales quadratically with the bit size fits the empirically generated data well.
// TODO: See if theoretical analysis of the modular exponentiation algorithm also justifies quadratic scaling.
}
} // benchmark
@@ -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.1/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.1/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.1/README.md#pinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/release/3.1/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.1/README.md#unpinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/release/3.1/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.1/README.md#test).
@@ -143,7 +143,7 @@ We now have an account that is available to have a contract assigned to it, enab
In the fourth terminal window, start a second `nodeos` instance. Notice that this command line is substantially longer than the one we used above to create the first producer. This is necessary to avoid collisions with the first `nodeos` instance. Fortunately, you can just cut and paste this command line and adjust the keys:
```sh
nodeos --producer-name inita --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin --http-server-address 127.0.0.1:8889 --p2p-listen-endpoint 127.0.0.1:9877 --p2p-peer-address 127.0.0.1:9876 --config-dir node2 --data-dir node2 --signature-provider EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg=KEY:5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr
nodeos --producer-name inita --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin --http-server-address 127.0.0.1:8889 --p2p-listen-endpoint 127.0.0.1:9877 --p2p-peer-address 127.0.0.1:9876 --config-dir node2 --data-dir node2 --private-key [\"EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg\",\"5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr\"]
```
The output from this new node will show a little activity but will stop reporting until the last step in this tutorial, when the `inita` account is registered as a producer account and activated. Here is some example output from a newly started node. Your output might look a little different, depending on how much time you took entering each of these commands. Furthermore, this example is only the last few lines of output:
+28 -21
View File
@@ -63,9 +63,6 @@ Config Options for eosio::chain_plugin:
--blocks-dir arg (="blocks") the location of the blocks directory
(absolute path or relative to
application data dir)
--state-dir arg (="state") the location of the state directory
(absolute path or relative to
application data dir)
--protocol-features-dir arg (="protocol_features")
the location of the protocol_features
directory (absolute path or relative to
@@ -119,18 +116,35 @@ Config Options for eosio::chain_plugin:
subjective whitelist/blacklist checks
applied to them (may specify multiple
times)
--read-mode arg (=head) Database read mode ("head",
"irreversible").
--read-mode arg (=speculative) Database read mode ("speculative",
"head", "read-only", "irreversible").
In "speculative" mode: database
contains state changes by transactions
in the blockchain up to the head block
as well as some transactions not yet
included in the blockchain.
In "head" mode: database contains state
changes up to the head block;
changes by only transactions in the
blockchain up to the head block;
transactions received by the node are
relayed if valid.
In "read-only" mode: (DEPRECATED: see
p2p-accept-transactions &
api-accept-transactions) database
contains state changes by only
transactions in the blockchain up to
the head block; transactions received
via the P2P network are not relayed and
transactions cannot be pushed via the
chain API.
In "irreversible" mode: database
contains state changes up to the last
irreversible block; transactions
received via the P2P network are not
relayed and transactions cannot be
pushed via the chain API.
contains state changes by only
transactions in the blockchain up to
the last irreversible block;
transactions received via the P2P
network are not relayed and
transactions cannot be pushed via the
chain API.
--api-accept-transactions arg (=1) Allow API transactions to be evaluated
and relayed if valid.
@@ -207,16 +221,9 @@ Config Options for eosio::chain_plugin:
transaction's Finality Status will
remain available from being first
identified.
--integrity-hash-on-start Log the state integrity hash on startup
--integrity-hash-on-stop Log the state integrity hash on
shutdown
--block-log-retain-blocks arg If set to greater than 0, periodically
prune the block log to store only
configured number of most recent
blocks.
If set to 0, no blocks are be written
to the block log; block log file is
removed after startup.
--block-log-retain-blocks arg if set, periodically prune the block
log to store only configured number of
most recent blocks
```
@@ -0,0 +1,39 @@
## Description
The `http_client_plugin` is an internal utility plugin, providing the `producer_plugin` the ability to use securely an external `keosd` instance as its block signer. It can only be used when the `producer_plugin` is configured to produce blocks.
## Usage
```console
# config.ini
plugin = eosio::http_client_plugin
https-client-root-cert = "path/to/my/certificate.pem"
https-client-validate-peers = 1
```
```sh
# command-line
nodeos ... --plugin eosio::http_client_plugin \
--https-client-root-cert "path/to/my/certificate.pem" \
--https-client-validate-peers 1
```
## Options
These can be specified from both the `nodeos` command-line or the `config.ini` file:
```console
Config Options for eosio::http_client_plugin:
--https-client-root-cert arg PEM encoded trusted root certificate
(or path to file containing one) used
to validate any TLS connections made.
(may specify multiple times)
--https-client-validate-peers arg (=1)
true: validate that the peer
certificates are valid and trusted,
false: ignore cert errors
```
## Dependencies
* [`producer_plugin`](../producer_plugin/index.md)
+13 -12
View File
@@ -29,10 +29,20 @@ Config Options for eosio::http_plugin:
The local IP and port to listen for
incoming http connections; set blank to
disable.
--https-server-address arg The local IP and port to listen for
incoming https connections; leave blank
to disable.
--https-certificate-chain-file arg Filename with the certificate chain to
present on https connections. PEM
format. Required for https.
--https-private-key-file arg Filename with https private key in PEM
format. Required for https
--https-ecdh-curve arg (=secp384r1) Configure https ECDH curve to use:
secp384r1 or prime256v1
--access-control-allow-origin arg Specify the Access-Control-Allow-Origin
to be returned on each request
to be returned on each request.
--access-control-allow-headers arg Specify the Access-Control-Allow-Header
s to be returned on each request
s to be returned on each request.
--access-control-max-age arg Specify the Access-Control-Max-Age to
be returned on each request.
--access-control-allow-credentials Specify if Access-Control-Allow-Credent
@@ -45,13 +55,7 @@ Config Options for eosio::http_plugin:
should use for processing http
requests. -1 for unlimited. 429 error
response when exceeded.
--http-max-in-flight-requests arg (=-1)
Maximum number of requests http_plugin
should use for processing http
requests. 429 error response when
exceeded.
--http-max-response-time-ms arg (=30) Maximum time for processing a request,
-1 for unlimited
--http-max-response-time-ms arg (=30) Maximum time for processing a request.
--verbose-http-errors Append the error log to HTTP responses
--http-validate-host arg (=1) If set to false, then any incoming
"Host" header is considered valid
@@ -62,9 +66,6 @@ Config Options for eosio::http_plugin:
by default.
--http-threads arg (=2) Number of worker threads in http thread
pool
--http-keep-alive arg (=1) If set to false, do not keep HTTP
connections alive, even if client
requests.
```
## Dependencies
+3
View File
@@ -11,7 +11,9 @@ For information on specific plugins, just select from the list below:
* [`chain_api_plugin`](chain_api_plugin/index.md)
* [`chain_plugin`](chain_plugin/index.md)
* [`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)
@@ -19,6 +21,7 @@ For information on specific plugins, just select from the list below:
* [`test_control_api_plugin`](test_control_api_plugin/index.md)
* [`test_control_plugin`](test_control_plugin/index.md)
* [`trace_api_plugin`](trace_api_plugin/index.md)
* [`txn_test_gen_plugin`](txn_test_gen_plugin/index.md)
[[info | Nodeos is modular]]
| Plugins add incremental functionality to `nodeos`. Unlike runtime plugins, `nodeos` plugins are built at compile-time.
@@ -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]
```
@@ -39,6 +39,10 @@ Config Options for eosio::producer_plugin:
-p [ --producer-name ] arg ID of producer controlled by this node
(e.g. inita; may specify multiple
times)
--private-key arg (DEPRECATED - Use signature-provider
instead) Tuple of [public key, WIF
private key] (may specify multiple
times)
--signature-provider arg (=EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3)
Key=Value pairs in the form
<public-key>=<provider-spec>
@@ -51,7 +55,7 @@ Config Options for eosio::producer_plugin:
form <provider-type>
:<data>
<provider-type> is KEY, KEOSD, or SE
<provider-type> is KEY, or KEOSD
KEY:<data> is a string form of
a valid EOS
@@ -64,6 +68,10 @@ Config Options for eosio::producer_plugin:
and the approptiate
wallet(s) are
unlocked
--keosd-provider-timeout arg (=5) Limits the maximum time (in
milliseconds) that is allowed for
sending blocks to a keosd provider for
signing
--greylist-account arg account that can not access to extended
CPU/NET virtual resources
--greylist-limit arg (=1000) Limit (between 1 and 1000) on the
@@ -98,10 +106,9 @@ Config Options for eosio::producer_plugin:
--max-scheduled-transaction-time-per-block-ms arg (=100)
Maximum wall-clock time, in
milliseconds, spent retiring scheduled
transactions (and incoming transactions
according to incoming-defer-ratio) in
any block before returning to normal
transaction processing.
transactions in any block before
returning to normal transaction
processing.
--subjective-cpu-leeway-us arg (=31000)
Time in microseconds allowed for a
transaction that starts with
@@ -122,6 +129,8 @@ Config Options for eosio::producer_plugin:
transaction queue. Exceeding this value
will subjectively drop transaction with
resource exhaustion.
--disable-api-persisted-trx Disable the re-apply of API
transactions.
--disable-subjective-billing arg (=1) Disable subjective CPU billing for
API/P2P transactions
--disable-subjective-account-billing arg
@@ -42,9 +42,6 @@ Config Options for eosio::state_history_plugin:
incoming connections. Caution: only
expose this port to your internal
network.
--state-history-unix-socket-path arg the path (relative to data-dir) to
create a unix socket upon which to
listen for incoming connections.
--trace-history-debug-mode enable debug mode for trace history
--state-history-log-retain-blocks arg if set, periodically prune the state
history files to store only configured
@@ -0,0 +1,40 @@
## Description
The `txn_test_gen_plugin` is used for transaction test purposes.
[[info | For More Information]]
For more information, check the [txn_test_gen_plugin/README.md](https://github.com/AntelopeIO/leap/tree/main/plugins/txn_test_gen_plugin) on the `AntelopeIO/leap` repository.
## Usage
```console
# config.ini
plugin = eosio::txn_test_gen_plugin
[options]
```
```sh
# command-line
nodeos ... --plugin eosio::txn_test_gen_plugin [options]
```
## Options
These can be specified from both the `nodeos` command-line or the `config.ini` file:
```console
Config Options for eosio::txn_test_gen_plugin:
--txn-reference-block-lag arg (=0) Lag in number of blocks from the head
block when selecting the reference
block for transactions (-1 means Last
Irreversible Block)
--txn-test-gen-threads arg (=2) Number of worker threads in
txn_test_gen thread pool
--txn-test-gen-account-prefix arg (=txn.test.)
Prefix to use for accounts generated
and used by this plugin
```
## Dependencies
None
@@ -64,24 +64,3 @@ Sample `logging.json`:
]
}
```
## Expected Output of Log Levels
* `error` - Log output that likely requires operator intervention.
- Error level logging should be reserved for conditions that are completely unexpected or otherwise need human intervention.
- Also used to indicate software errors such as: impossible values for an `enum`, out of bounds array access, null pointers, or other conditions that likely will throw an exception.
- *Note*: Currently, there are numerous `error` level logging that likely should be `warn` as they do not require human intervention. The `net_plugin_impl`, for example, has a number of `error` level logs for bad network connections. This is handled and processed correctly. These should be changed to `warn` or `info`.
* `warn` - Log output indicating unexpected but recoverable errors.
- Although, `warn` level typically does not require human intervention, repeated output of `warn` level logs might indicate actions needed by an operator.
- `warn` should not be used simply for conveying information. A `warn` level log is something to take notice of, but not necessarily be concerned about.
* `info` (default) - Log output that provides useful information to an operator.
- Can be just progress indication or other useful data to a user. Care is taken not to create excessive log output with `info` level logging. For example, no `info` level logging should be produced for every transaction.
- For progress indication, some multiple of transactions should be processed between each log output; typically, every 1000 transactions.
* `debug` - Useful log output for when non-default logging is enabled.
- Answers the question: is this useful information for a user that is monitoring the log output. Care should be taken not to create excessive log output; similar to `info` level logging.
- Enabling `debug` level logging should provide greater insight into behavior without overwhelming the output with log entries.
- `debug` level should not be used for *trace* level logging; to that end, use `all` (see below).
- Like `info`, no `debug` level logging should be produced for every transaction. There are specific transaction level loggers dedicated to transaction level logging: `transaction`, `transaction_trace_failure`, `transaction_trace_success`, `transaction_failure_tracing`, `transaction_success_tracing`, `transient_trx_success_tracing`, `transient_trx_failure_tracing`.
* `all` (trace) - For logging that would be overwhelming if `debug` level logging were used.
- Can be used for trace level logging. Only used in a few places and not completely supported.
- *Note*: In the future a different logging library may provide better trace level logging support. The current logging framework is not performant enough to enable excess trace level output.
@@ -27,17 +27,38 @@ The `nodeos` service provides query access to the chain database via the HTTP [R
The `nodeos` service can be run in different "read" modes. These modes control how the node operates and how it processes blocks and transactions:
- `speculative`: this includes the side effects of confirmed and unconfirmed transactions.
- `head`: this only includes the side effects of confirmed transactions, this mode processes unconfirmed transactions but does not include them.
- `read-only`: this mode is deprecated. Similar functionality can be achieved by combining options: `read-mode = head`, `p2p-accept-transactions = false`, `api-accept-transactions = false`. When these options are set, the local database will contain state changes made by transactions in the chain up to the head block. Also, transactions received via the P2P network are not relayed and transactions cannot be pushed via the chain API.
- `irreversible`: this mode also includes confirmed transactions only up to those included in the last irreversible block.
A transaction is considered confirmed when a `nodeos` instance has received, processed, and written it to a block on the blockchain, i.e. it is in the head block or an earlier block.
### Speculative Mode
Clients such as `cleos` and the RPC API, will see database state as of the current head block plus changes made by all transactions known to this node but potentially not included in the chain, unconfirmed transactions for example.
Speculative mode is low latency but fragile, there is no guarantee that the transactions reflected in the state will be included in the chain OR that they will reflected in the same order the state implies.
This mode features the lowest latency, but is the least consistent.
In speculative mode `nodeos` is able to execute transactions which have TaPoS (Transaction as Proof of Stake) pointing to any valid block in a fork considered to be the best fork by this node.
### Head Mode
Clients such as `cleos` and the RPC API will see database state as of the current head block of the chain. Since current head block is not yet irreversible and short-lived forks are possible, state read in this mode may become inaccurate if `nodeos` switches to a better fork.
Clients such as `cleos` and the RPC API will see database state as of the current head block of the chain. Since current head block is not yet irreversible and short-lived forks are possible, state read in this mode may become inaccurate if `nodeos` switches to a better fork. Note that this is also true of speculative mode.
This mode represents a good trade-off between highly consistent views of the data and latency.
In this mode `nodeos` is able to execute transactions which have TaPoS pointing to any valid block in a fork considered to be the best fork by this node.
### Read-Only Mode
[[caution | Deprecation Notice]]
| The explicit `read-mode = read-only` mode is deprecated. Similar functionality can now be achieved in `head` mode by combining options: `read-mode = head`, `p2p-accept-transactions = false`, `api-accept-transactions = false`.
Clients such as `cleos` and the RPC API will see database state as of the current head block of the chain. It **will not** include changes made by transactions known to this node but not included in the chain, such as unconfirmed transactions.
### Irreversible Mode
When `nodeos` is configured to be in irreversible read mode, it will still track the most up-to-date blocks in the fork database, but the state will lag behind the current best head block, sometimes referred to as the fork DB head, to always reflect the state of the last irreversible block.
+15
View File
@@ -44,6 +44,16 @@ Config Options for eosio::http_plugin:
--http-server-address arg The local IP and port to listen for
incoming http connections; leave blank
to disable.
--https-server-address arg The local IP and port to listen for
incoming https connections; leave blank
to disable.
--https-certificate-chain-file arg Filename with the certificate chain to
present on https connections. PEM
format. Required for https.
--https-private-key-file arg Filename with https private key in PEM
format. Required for https
--https-ecdh-curve arg (=secp384r1) Configure https ECDH curve to use:
secp384r1 or prime256v1
--access-control-allow-origin arg Specify the Access-Control-Allow-Origin
to be returned on each request.
--access-control-allow-headers arg Specify the Access-Control-Allow-Header
@@ -81,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
+5
View File
@@ -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)
+38
View File
@@ -0,0 +1,38 @@
---
content_title: eosio-blocklog
link_text: eosio-blocklog
---
`eosio-blocklog` is a command-line interface (CLI) utility that allows node operators to perform low-level tasks on the block logs created by a `nodeos` instance. `eosio-blocklog` can perform one of the following operations:
* Convert a range of blocks to JSON format, as single objects or array.
* Generate `blocks.index` from `blocks.log` in blocks directory.
* Trim `blocks.log` and `blocks.index` between a range of blocks.
* Perform consistency test between `blocks.log` and `blocks.index`.
* Output the results of the operation to a file or `stdout` (default).
## Usage
```sh
eosio-blocklog <options> ...
```
## Options
Option (=default) | Description
-|-
`--blocks-dir arg (="blocks")` | The location of the blocks directory (absolute path or relative to the current directory)
`-o [ --output-file ] arg` | The file to write the generated output to (absolute or relative path). If not specified then output is to `stdout`
`-f [ --first ] arg (=0)` | The first block number to log or the first block to keep if `trim-blocklog` specified
`-l [ --last ] arg (=4294967295)` | the last block number to log or the last block to keep if `trim-blocklog` specified
`--no-pretty-print` | Do not pretty print the output. Useful if piping to `jq` to improve performance
`--as-json-array` | Print out JSON blocks wrapped in JSON array (otherwise the output is free-standing JSON objects)
`--make-index` | Create `blocks.index` from `blocks.log`. Must give `blocks-dir` location. Give `output-file` relative to current directory or absolute path (default is `<blocks-dir>/blocks.index`)
`--trim-blocklog` | Trim `blocks.log` and `blocks.index`. Must give `blocks-dir` and `first` and/or `last` options.
`--smoke-test` | Quick test that `blocks.log` and `blocks.index` are well formed and agree with each other
`-h [ --help ]` | Print this help message and exit
## Remarks
When `eosio-blocklog` is launched, the utility attempts to perform the specified operation, then yields the following possible outcomes:
* If successful, the selected operation is performed and the utility terminates with a zero error code (no error).
* If unsuccessful, the utility outputs an error to `stderr` and terminates with a non-zero error code (indicating an error).
+1
View File
@@ -5,4 +5,5 @@ link_text: Antelope Utilities
This section contains documentation for additional utilities that complement or extend `nodeos` and potentially other Antelope software:
* [eosio-blocklog](eosio-blocklog.md) - Low-level utility for node operators to interact with block log files.
* [trace_api_util](trace_api_util.md) - Low-level utility for performing tasks associated with the [Trace API](../01_nodeos/03_plugins/trace_api_plugin/index.md).
+20 -5
View File
@@ -3,21 +3,23 @@ set(FC_INSTALL_COMPONENT "dev")
set(APPBASE_INSTALL_COMPONENT "dev")
set(SOFTFLOAT_INSTALL_COMPONENT "dev")
set(EOSVM_INSTALL_COMPONENT "dev")
set(BN256_INSTALL_COMPONENT "dev")
add_subdirectory( libfc )
add_subdirectory( fc )
add_subdirectory( builtins )
# Suppress warnings on 3rdParty Library
add_definitions( -w )
add_subdirectory( softfloat )
add_subdirectory( wasm-jit )
remove_definitions( -w )
add_subdirectory( chainbase )
set(APPBASE_ENABLE_AUTO_VERSION OFF CACHE BOOL "enable automatic discovery of version via 'git describe'")
add_subdirectory( appbase )
add_subdirectory( custom_appbase )
add_subdirectory( chain )
add_subdirectory( testing )
add_subdirectory( version )
add_subdirectory( state_history )
add_subdirectory( cli11 )
set(USE_EXISTING_SOFTFLOAT ON CACHE BOOL "use pre-exisiting softfloat lib")
set(ENABLE_TOOLS OFF CACHE BOOL "Build tools")
@@ -28,4 +30,17 @@ 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()
add_subdirectory( prometheus )
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}")
+5 -5
View File
@@ -42,7 +42,7 @@ if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES)
endif()
llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native orcjit)
include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
option(EOSVMOC_ENABLE_DEVELOPER_OPTIONS "enable developer options for EOS VM OC" OFF)
@@ -72,9 +72,6 @@ set(CHAIN_WEBASSEMBLY_SOURCES
webassembly/transaction.cpp
)
add_library(eosio_rapidjson INTERFACE)
target_include_directories(eosio_rapidjson INTERFACE ../rapidjson/include)
## SORT .cpp by most likely to change / break compile
add_library( eosio_chain
merkle.cpp
@@ -128,7 +125,7 @@ add_library( eosio_chain
${HEADERS}
)
target_link_libraries( eosio_chain PUBLIC bn256 fc chainbase eosio_rapidjson Logging IR WAST WASM Runtime
target_link_libraries( eosio_chain PUBLIC fc chainbase Logging IR WAST WASM Runtime
softfloat builtins ${CHAIN_EOSVM_LIBRARIES} ${LLVM_LIBS} ${CHAIN_RT_LINKAGE}
)
target_include_directories( eosio_chain
@@ -165,3 +162,6 @@ install( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/eosio/chain/
FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h" EXCLUDE
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/eosio/chain/core_symbol.hpp DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/eosio/chain COMPONENT dev EXCLUDE_FROM_ALL)
#if(MSVC)
# set_source_files_properties( db_init.cpp db_block.cpp database.cpp block_log.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )
#endif(MSVC)
+29 -50
View File
@@ -70,14 +70,14 @@ namespace eosio { namespace chain {
);
}
abi_serializer::abi_serializer( abi_def abi, const yield_function_t& yield ) {
abi_serializer::abi_serializer( const abi_def& abi, const yield_function_t& yield ) {
configure_built_in_types();
set_abi(std::move(abi), yield);
set_abi(abi, yield);
}
abi_serializer::abi_serializer( const abi_def& abi, const fc::microseconds& max_serialization_time) {
configure_built_in_types();
set_abi(abi, create_yield_function(max_serialization_time));
set_abi(abi, max_serialization_time);
}
void abi_serializer::add_specialized_unpack_pack( const string& name,
@@ -128,19 +128,11 @@ namespace eosio { namespace chain {
built_in_types.emplace("extended_asset", pack_unpack<extended_asset>());
}
void abi_serializer::set_abi(abi_def abi, const yield_function_t& yield) {
void abi_serializer::set_abi(const abi_def& abi, const yield_function_t& yield) {
impl::abi_traverse_context ctx(yield);
EOS_ASSERT(starts_with(abi.version, "eosio::abi/1."), unsupported_abi_version_exception, "ABI has an unsupported version");
size_t types_size = abi.types.size();
size_t structs_size = abi.structs.size();
size_t actions_size = abi.actions.size();
size_t tables_size = abi.tables.size();
size_t error_messages_size = abi.error_messages.size();
size_t variants_size = abi.variants.value.size();
size_t action_results_size = abi.action_results.value.size();
typedefs.clear();
structs.clear();
actions.clear();
@@ -149,41 +141,41 @@ namespace eosio { namespace chain {
variants.clear();
action_results.clear();
for( auto& st : abi.structs )
structs[st.name] = std::move(st);
for( const auto& st : abi.structs )
structs[st.name] = st;
for( auto& td : abi.types ) {
for( const auto& td : abi.types ) {
EOS_ASSERT(!_is_type(td.new_type_name, ctx), duplicate_abi_type_def_exception,
"type already exists", ("new_type_name",impl::limit_size(td.new_type_name)));
typedefs[std::move(td.new_type_name)] = std::move(td.type);
typedefs[td.new_type_name] = td.type;
}
for( auto& a : abi.actions )
actions[std::move(a.name)] = std::move(a.type);
for( const auto& a : abi.actions )
actions[a.name] = a.type;
for( auto& t : abi.tables )
tables[std::move(t.name)] = std::move(t.type);
for( const auto& t : abi.tables )
tables[t.name] = t.type;
for( auto& e : abi.error_messages )
error_messages[std::move(e.error_code)] = std::move(e.error_msg);
for( const auto& e : abi.error_messages )
error_messages[e.error_code] = e.error_msg;
for( auto& v : abi.variants.value )
variants[v.name] = std::move(v);
for( const auto& v : abi.variants.value )
variants[v.name] = v;
for( auto& r : abi.action_results.value )
action_results[std::move(r.name)] = std::move(r.result_type);
for( const auto& r : abi.action_results.value )
action_results[r.name] = r.result_type;
/**
* The ABI vector may contain duplicates which would make it
* an invalid ABI
*/
EOS_ASSERT( typedefs.size() == types_size, duplicate_abi_type_def_exception, "duplicate type definition detected" );
EOS_ASSERT( structs.size() == structs_size, duplicate_abi_struct_def_exception, "duplicate struct definition detected" );
EOS_ASSERT( actions.size() == actions_size, duplicate_abi_action_def_exception, "duplicate action definition detected" );
EOS_ASSERT( tables.size() == tables_size, duplicate_abi_table_def_exception, "duplicate table definition detected" );
EOS_ASSERT( error_messages.size() == error_messages_size, duplicate_abi_err_msg_def_exception, "duplicate error message definition detected" );
EOS_ASSERT( variants.size() == variants_size, duplicate_abi_variant_def_exception, "duplicate variant definition detected" );
EOS_ASSERT( action_results.size() == action_results_size, duplicate_abi_action_results_def_exception, "duplicate action results definition detected" );
EOS_ASSERT( typedefs.size() == abi.types.size(), duplicate_abi_type_def_exception, "duplicate type definition detected" );
EOS_ASSERT( structs.size() == abi.structs.size(), duplicate_abi_struct_def_exception, "duplicate struct definition detected" );
EOS_ASSERT( actions.size() == abi.actions.size(), duplicate_abi_action_def_exception, "duplicate action definition detected" );
EOS_ASSERT( tables.size() == abi.tables.size(), duplicate_abi_table_def_exception, "duplicate table definition detected" );
EOS_ASSERT( error_messages.size() == abi.error_messages.size(), duplicate_abi_err_msg_def_exception, "duplicate error message definition detected" );
EOS_ASSERT( variants.size() == abi.variants.value.size(), duplicate_abi_variant_def_exception, "duplicate variant definition detected" );
EOS_ASSERT( action_results.size() == abi.action_results.value.size(), duplicate_abi_action_results_def_exception, "duplicate action results definition detected" );
validate(ctx);
}
@@ -217,19 +209,6 @@ namespace eosio { namespace chain {
return ends_with(type, "[]");
}
bool abi_serializer::is_szarray(const string_view& type)const {
auto pos1 = type.find_last_of('[');
auto pos2 = type.find_last_of(']');
if(pos1 == string_view::npos || pos2 == string_view::npos) return false;
auto pos = pos1 + 1;
if(pos == pos2) return false;
while(pos < pos2) {
if( ! (type[pos] >= '0' && type[pos] <= '9') ) return false;
++pos;
}
return true;
}
bool abi_serializer::is_optional(const string_view& type)const {
return ends_with(type, "?");
}
@@ -246,8 +225,6 @@ namespace eosio { namespace chain {
std::string_view abi_serializer::fundamental_type(const std::string_view& type)const {
if( is_array(type) ) {
return type.substr(0, type.size()-2);
} else if (is_szarray (type) ){
return type.substr(0, type.find_last_of('['));
} else if ( is_optional(type) ) {
return type.substr(0, type.size()-1);
} else {
@@ -418,8 +395,10 @@ namespace eosio { namespace chain {
for( decltype(size.value) i = 0; i < size; ++i ) {
ctx.set_array_index_of_path_back(i);
auto v = _binary_to_variant(ftype, stream, ctx);
// The exception below is commented out to allow array of optional as input data
//EOS_ASSERT( !v.is_null(), unpack_exception, "Invalid packed array '${p}'", ("p", ctx.get_path_string()) );
// QUESTION: Is it actually desired behavior to require the returned variant to not be null?
// This would disallow arrays of optionals in general (though if all optionals in the array were present it would be allowed).
// Is there any scenario in which the returned variant would be null other than in the case of an empty optional?
EOS_ASSERT( !v.is_null(), unpack_exception, "Invalid packed array '${p}'", ("p", ctx.get_path_string()) );
vars.emplace_back(std::move(v));
}
// QUESTION: Why would the assert below ever fail?
+83 -101
View File
@@ -71,53 +71,51 @@ void apply_context::exec_one()
try {
action_return_value.clear();
receiver_account = &db.get<account_metadata_object,by_name>( receiver );
if( !(context_free && control.skip_trx_checks()) ) {
privileged = receiver_account->is_privileged();
auto native = control.find_apply_handler( receiver, act->account, act->name );
if( native ) {
if( trx_context.enforce_whiteblacklist && control.is_speculative_block() ) {
control.check_contract_list( receiver );
control.check_action_list( act->account, act->name );
}
(*native)( *this );
privileged = receiver_account->is_privileged();
auto native = control.find_apply_handler( receiver, act->account, act->name );
if( native ) {
if( trx_context.enforce_whiteblacklist && control.is_producing_block() ) {
control.check_contract_list( receiver );
control.check_action_list( act->account, act->name );
}
(*native)( *this );
}
if( ( receiver_account->code_hash != digest_type() ) &&
( !( act->account == config::system_account_name
&& act->name == "setcode"_n
&& receiver == config::system_account_name )
|| control.is_builtin_activated( builtin_protocol_feature_t::forward_setcode )
)
) {
if( trx_context.enforce_whiteblacklist && control.is_speculative_block() ) {
control.check_contract_list( receiver );
control.check_action_list( act->account, act->name );
}
try {
control.get_wasm_interface().apply( receiver_account->code_hash, receiver_account->vm_type, receiver_account->vm_version, *this );
} catch( const wasm_exit& ) {}
if( ( receiver_account->code_hash != digest_type() ) &&
( !( act->account == config::system_account_name
&& act->name == "setcode"_n
&& receiver == config::system_account_name )
|| control.is_builtin_activated( builtin_protocol_feature_t::forward_setcode )
)
) {
if( trx_context.enforce_whiteblacklist && control.is_producing_block() ) {
control.check_contract_list( receiver );
control.check_action_list( act->account, act->name );
}
try {
control.get_wasm_interface().apply( receiver_account->code_hash, receiver_account->vm_type, receiver_account->vm_version, *this );
} catch( const wasm_exit& ) {}
}
if( !privileged && control.is_builtin_activated( builtin_protocol_feature_t::ram_restrictions ) ) {
const size_t checktime_interval = 10;
size_t counter = 0;
bool not_in_notify_context = (receiver == act->account);
const auto end = _account_ram_deltas.end();
for( auto itr = _account_ram_deltas.begin(); itr != end; ++itr, ++counter ) {
if( counter == checktime_interval ) {
trx_context.checktime();
counter = 0;
}
if( itr->delta > 0 && itr->account != receiver ) {
EOS_ASSERT( not_in_notify_context, unauthorized_ram_usage_increase,
"unprivileged contract cannot increase RAM usage of another account within a notify context: ${account}",
("account", itr->account)
);
EOS_ASSERT( has_authorization( itr->account ), unauthorized_ram_usage_increase,
"unprivileged contract cannot increase RAM usage of another account that has not authorized the action: ${account}",
("account", itr->account)
);
}
if( !privileged && control.is_builtin_activated( builtin_protocol_feature_t::ram_restrictions ) ) {
const size_t checktime_interval = 10;
size_t counter = 0;
bool not_in_notify_context = (receiver == act->account);
const auto end = _account_ram_deltas.end();
for( auto itr = _account_ram_deltas.begin(); itr != end; ++itr, ++counter ) {
if( counter == checktime_interval ) {
trx_context.checktime();
counter = 0;
}
if( itr->delta > 0 && itr->account != receiver ) {
EOS_ASSERT( not_in_notify_context, unauthorized_ram_usage_increase,
"unprivileged contract cannot increase RAM usage of another account within a notify context: ${account}",
("account", itr->account)
);
EOS_ASSERT( has_authorization( itr->account ), unauthorized_ram_usage_increase,
"unprivileged contract cannot increase RAM usage of another account that has not authorized the action: ${account}",
("account", itr->account)
);
}
}
}
@@ -182,7 +180,7 @@ void apply_context::exec_one()
print_debug(receiver, trace);
}
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient()))
if (auto dm_logger = control.get_deep_mind_logger())
{
dm_logger->on_end_action();
}
@@ -289,7 +287,7 @@ void apply_context::require_recipient( account_name recipient ) {
schedule_action( action_ordinal, recipient, false )
);
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_require_recipient();
}
}
@@ -316,12 +314,12 @@ void apply_context::execute_inline( action&& a ) {
EOS_ASSERT( code != nullptr, action_validate_exception,
"inline action's code account ${account} does not exist", ("account", a.account) );
bool enforce_actor_whitelist_blacklist = trx_context.enforce_whiteblacklist && control.is_speculative_block();
bool enforce_actor_whitelist_blacklist = trx_context.enforce_whiteblacklist && control.is_producing_block();
flat_set<account_name> actors;
bool disallow_send_to_self_bypass = control.is_builtin_activated( builtin_protocol_feature_t::restrict_action_to_self );
bool send_to_self = (a.account == receiver);
bool inherit_parent_authorizations = (!disallow_send_to_self_bypass && send_to_self && (receiver == act->account) && control.is_speculative_block());
bool inherit_parent_authorizations = (!disallow_send_to_self_bypass && send_to_self && (receiver == act->account) && control.is_producing_block());
flat_set<permission_level> inherited_authorizations;
if( inherit_parent_authorizations ) {
@@ -347,14 +345,14 @@ void apply_context::execute_inline( action&& a ) {
control.check_actor_list( actors );
}
if( !privileged && control.is_speculative_block() ) {
if( !privileged && control.is_producing_block() ) {
const auto& chain_config = control.get_global_properties().configuration;
EOS_ASSERT( a.data.size() < std::min(chain_config.max_inline_action_size, control.get_max_nonprivileged_inline_action_size()),
inline_action_too_big_nonprivileged,
"inline action too big for nonprivileged account ${account}", ("account", a.account));
}
// No need to check authorization if replaying irreversible blocks or contract is privileged
if( !control.skip_auth_check() && !privileged && !trx_context.is_read_only() ) {
if( !control.skip_auth_check() && !privileged ) {
try {
control.get_authorization_manager()
.check_authorization( {a},
@@ -363,7 +361,7 @@ void apply_context::execute_inline( action&& a ) {
control.pending_block_time() - trx_context.published,
std::bind(&transaction_context::checktime, &this->trx_context),
false,
trx_context.is_dry_run(), // check_but_dont_fail
trx_context.is_read_only,
inherited_authorizations
);
@@ -373,7 +371,7 @@ void apply_context::execute_inline( action&& a ) {
} catch( const fc::exception& e ) {
if( disallow_send_to_self_bypass || !send_to_self ) {
throw;
} else if( control.is_speculative_block() ) {
} else if( control.is_producing_block() ) {
subjective_block_production_exception new_exception(FC_LOG_MESSAGE( error, "Authorization failure with inline action sent to self"));
for (const auto& log: e.get_log()) {
new_exception.append_log(log);
@@ -383,7 +381,7 @@ void apply_context::execute_inline( action&& a ) {
} catch( ... ) {
if( disallow_send_to_self_bypass || !send_to_self ) {
throw;
} else if( control.is_speculative_block() ) {
} else if( control.is_producing_block() ) {
EOS_THROW(subjective_block_production_exception, "Unexpected exception occurred validating inline action sent to self");
}
}
@@ -394,7 +392,7 @@ void apply_context::execute_inline( action&& a ) {
schedule_action( std::move(a), inline_receiver, false )
);
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_send_inline();
}
}
@@ -407,7 +405,7 @@ void apply_context::execute_context_free_inline( action&& a ) {
EOS_ASSERT( a.authorization.size() == 0, action_validate_exception,
"context-free actions cannot have authorizations" );
if( !privileged && control.is_speculative_block() ) {
if( !privileged && control.is_producing_block() ) {
const auto& chain_config = control.get_global_properties().configuration;
EOS_ASSERT( a.data.size() < std::min(chain_config.max_inline_action_size, control.get_max_nonprivileged_inline_action_size()),
inline_action_too_big_nonprivileged,
@@ -419,17 +417,16 @@ void apply_context::execute_context_free_inline( action&& a ) {
schedule_action( std::move(a), inline_receiver, true )
);
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_send_context_free_inline();
}
}
void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, account_name payer, transaction&& trx, bool replace_existing ) {
EOS_ASSERT( !trx_context.is_read_only(), transaction_exception, "cannot schedule a deferred transaction from within a readonly transaction" );
EOS_ASSERT( trx.context_free_actions.size() == 0, cfa_inside_generated_tx, "context free actions are not currently allowed in generated transactions" );
bool enforce_actor_whitelist_blacklist = trx_context.enforce_whiteblacklist && control.is_speculative_block()
bool enforce_actor_whitelist_blacklist = trx_context.enforce_whiteblacklist && control.is_producing_block()
&& !control.sender_avoids_whitelist_blacklist_enforcement( receiver );
trx_context.validate_referenced_accounts( trx, enforce_actor_whitelist_blacklist );
@@ -531,7 +528,7 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
} catch( const fc::exception& e ) {
if( disallow_send_to_self_bypass || !is_sending_only_to_self(receiver) ) {
throw;
} else if( control.is_speculative_block() ) {
} else if( control.is_producing_block() ) {
subjective_block_production_exception new_exception(FC_LOG_MESSAGE( error, "Authorization failure with sent deferred transaction consisting only of actions to self"));
for (const auto& log: e.get_log()) {
new_exception.append_log(log);
@@ -541,7 +538,7 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
} catch( ... ) {
if( disallow_send_to_self_bypass || !is_sending_only_to_self(receiver) ) {
throw;
} else if( control.is_speculative_block() ) {
} else if( control.is_producing_block() ) {
EOS_THROW(subjective_block_production_exception, "Unexpected exception occurred validating sent deferred transaction consisting only of actions to self");
}
}
@@ -553,12 +550,12 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
bool replace_deferred_activated = control.is_builtin_activated(builtin_protocol_feature_t::replace_deferred);
EOS_ASSERT( replace_deferred_activated || !control.is_speculative_block()
EOS_ASSERT( replace_deferred_activated || !control.is_producing_block()
|| control.all_subjective_mitigations_disabled(),
subjective_block_production_exception,
"Replacing a deferred transaction is temporarily disabled." );
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_ram_trace(RAM_EVENT_ID("${id}", ("id", ptr->id)), "deferred_trx", "cancel", "deferred_trx_cancel");
}
@@ -576,7 +573,7 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
trx_id_for_new_obj = ptr->trx_id;
}
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_cancel_deferred(deep_mind_handler::operation_qualifier::modify, *ptr);
}
@@ -593,7 +590,7 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
trx_size = gtx.set( trx );
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_send_deferred(deep_mind_handler::operation_qualifier::modify, gtx);
dm_logger->on_ram_trace(RAM_EVENT_ID("${id}", ("id", gtx.id)), "deferred_trx", "update", "deferred_trx_add");
}
@@ -610,7 +607,7 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
trx_size = gtx.set( trx );
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_send_deferred(deep_mind_handler::operation_qualifier::none, gtx);
dm_logger->on_ram_trace(RAM_EVENT_ID("${id}", ("id", gtx.id)), "deferred_trx", "add", "deferred_trx_add");
}
@@ -627,11 +624,10 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
}
bool apply_context::cancel_deferred_transaction( const uint128_t& sender_id, account_name sender ) {
EOS_ASSERT( !trx_context.is_read_only(), transaction_exception, "cannot cancel a deferred transaction from within a readonly transaction" );
auto& generated_transaction_idx = db.get_mutable_index<generated_transaction_multi_index>();
const auto* gto = db.find<generated_transaction_object,by_sender_id>(boost::make_tuple(sender, sender_id));
if ( gto ) {
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_cancel_deferred(deep_mind_handler::operation_qualifier::none, *gto);
dm_logger->on_ram_trace(RAM_EVENT_ID("${id}", ("id", gto->id)), "deferred_trx", "cancel", "deferred_trx_cancel");
}
@@ -672,7 +668,7 @@ const table_id_object& apply_context::find_or_create_table( name code, name scop
return *existing_tid;
}
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
std::string event_id = RAM_EVENT_ID("${code}:${scope}:${table}",
("code", code)
("scope", scope)
@@ -689,14 +685,14 @@ const table_id_object& apply_context::find_or_create_table( name code, name scop
t_id.table = table;
t_id.payer = payer;
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_create_table(t_id);
}
});
}
void apply_context::remove_table( const table_id_object& tid ) {
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
std::string event_id = RAM_EVENT_ID("${code}:${scope}:${table}",
("code", tid.code)
("scope", tid.scope)
@@ -707,7 +703,7 @@ void apply_context::remove_table( const table_id_object& tid ) {
update_db_usage(tid.payer, - config::billable_size_v<table_id_object>);
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_remove_table(tid);
}
@@ -780,13 +776,11 @@ int apply_context::get_context_free_data( uint32_t index, char* buffer, size_t b
}
int apply_context::db_store_i64( name scope, name table, const account_name& payer, uint64_t id, const char* buffer, size_t buffer_size ) {
EOS_ASSERT( !trx_context.is_read_only(), table_operation_not_permitted, "cannot store a db record when executing a readonly transaction" );
return db_store_i64( receiver, scope, table, payer, id, buffer, buffer_size);
}
int apply_context::db_store_i64( name code, name scope, name table, const account_name& payer, uint64_t id, const char* buffer, size_t buffer_size ) {
// require_write_lock( scope );
EOS_ASSERT( !trx_context.is_read_only(), table_operation_not_permitted, "cannot store a db record when executing a readonly transaction" );
const auto& tab = find_or_create_table( code, scope, table, payer );
auto tableid = tab.id;
@@ -805,7 +799,7 @@ int apply_context::db_store_i64( name code, name scope, name table, const accoun
int64_t billable_size = (int64_t)(buffer_size + config::billable_size_v<key_value_object>);
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
std::string event_id = RAM_EVENT_ID("${table_code}:${scope}:${table_name}:${primkey}",
("table_code", tab.code)
("scope", tab.scope)
@@ -817,7 +811,7 @@ int apply_context::db_store_i64( name code, name scope, name table, const accoun
update_db_usage( payer, billable_size);
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_db_store_i64(tab, obj);
}
@@ -826,7 +820,6 @@ int apply_context::db_store_i64( name code, name scope, name table, const accoun
}
void apply_context::db_update_i64( int iterator, account_name payer, const char* buffer, size_t buffer_size ) {
EOS_ASSERT( !trx_context.is_read_only(), table_operation_not_permitted, "cannot update a db record when executing a readonly transaction" );
const key_value_object& obj = keyval_cache.get( iterator );
const auto& table_obj = keyval_cache.get_table( obj.t_id );
@@ -841,7 +834,7 @@ void apply_context::db_update_i64( int iterator, account_name payer, const char*
if( payer == account_name() ) payer = obj.payer;
std::string event_id;
if (control.get_deep_mind_logger(trx_context.is_transient()) != nullptr) {
if (control.get_deep_mind_logger() != nullptr) {
event_id = RAM_EVENT_ID("${table_code}:${scope}:${table_name}:${primkey}",
("table_code", table_obj.code)
("scope", table_obj.scope)
@@ -852,27 +845,27 @@ void apply_context::db_update_i64( int iterator, account_name payer, const char*
if( account_name(obj.payer) != payer ) {
// refund the existing payer
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient()))
if (auto dm_logger = control.get_deep_mind_logger())
{
dm_logger->on_ram_trace(std::string(event_id), "table_row", "remove", "primary_index_update_remove_old_payer");
}
update_db_usage( obj.payer, -(old_size) );
// charge the new payer
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient()))
if (auto dm_logger = control.get_deep_mind_logger())
{
dm_logger->on_ram_trace(std::move(event_id), "table_row", "add", "primary_index_update_add_new_payer");
}
update_db_usage( payer, (new_size));
} else if(old_size != new_size) {
// charge/refund the existing payer the difference
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient()))
if (auto dm_logger = control.get_deep_mind_logger())
{
dm_logger->on_ram_trace(std::move(event_id) , "table_row", "update", "primary_index_update");
}
update_db_usage( obj.payer, new_size - old_size);
}
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_db_update_i64(table_obj, obj, payer, buffer, buffer_size);
}
@@ -883,7 +876,6 @@ void apply_context::db_update_i64( int iterator, account_name payer, const char*
}
void apply_context::db_remove_i64( int iterator ) {
EOS_ASSERT( !trx_context.is_read_only(), table_operation_not_permitted, "cannot remove a db record when executing a readonly transaction" );
const key_value_object& obj = keyval_cache.get( iterator );
const auto& table_obj = keyval_cache.get_table( obj.t_id );
@@ -891,7 +883,7 @@ void apply_context::db_remove_i64( int iterator ) {
// require_write_lock( table_obj.scope );
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
std::string event_id = RAM_EVENT_ID("${table_code}:${scope}:${table_name}:${primkey}",
("table_code", table_obj.code)
("scope", table_obj.scope)
@@ -903,7 +895,7 @@ void apply_context::db_remove_i64( int iterator ) {
update_db_usage( obj.payer, -(obj.value.size() + config::billable_size_v<key_value_object>) );
if (auto dm_logger = control.get_deep_mind_logger(trx_context.is_transient())) {
if (auto dm_logger = control.get_deep_mind_logger()) {
dm_logger->on_db_remove_i64(table_obj, obj);
}
@@ -1035,27 +1027,17 @@ int apply_context::db_end_i64( name code, name scope, name table ) {
uint64_t apply_context::next_global_sequence() {
const auto& p = control.get_dynamic_global_properties();
if ( trx_context.is_read_only() ) {
// To avoid confusion of duplicated global sequence number, hard code to be 0.
return 0;
} else {
db.modify( p, [&]( auto& dgp ) {
++dgp.global_action_sequence;
});
return p.global_action_sequence;
}
db.modify( p, [&]( auto& dgp ) {
++dgp.global_action_sequence;
});
return p.global_action_sequence;
}
uint64_t apply_context::next_recv_sequence( const account_metadata_object& receiver_account ) {
if ( trx_context.is_read_only() ) {
// To avoid confusion of duplicated receive sequence number, hard code to be 0.
return 0;
} else {
db.modify( receiver_account, [&]( auto& ra ) {
++ra.recv_sequence;
});
return receiver_account.recv_sequence;
}
db.modify( receiver_account, [&]( auto& ra ) {
++ra.recv_sequence;
});
return receiver_account.recv_sequence;
}
uint64_t apply_context::next_auth_sequence( account_name actor ) {
const auto& amo = db.get<account_metadata_object,by_name>( actor );
+7 -9
View File
@@ -134,7 +134,6 @@ namespace eosio { namespace chain {
permission_name name,
permission_id_type parent,
const authority& auth,
bool is_trx_transient,
time_point initial_creation_time
)
{
@@ -159,7 +158,7 @@ namespace eosio { namespace chain {
p.last_updated = creation_time;
p.auth = auth;
if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) {
if (auto dm_logger = _control.get_deep_mind_logger()) {
dm_logger->on_create_permission(p);
}
});
@@ -170,7 +169,6 @@ namespace eosio { namespace chain {
permission_name name,
permission_id_type parent,
authority&& auth,
bool is_trx_transient,
time_point initial_creation_time
)
{
@@ -195,20 +193,20 @@ namespace eosio { namespace chain {
p.last_updated = creation_time;
p.auth = std::move(auth);
if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) {
if (auto dm_logger = _control.get_deep_mind_logger()) {
dm_logger->on_create_permission(p);
}
});
return perm;
}
void authorization_manager::modify_permission( const permission_object& permission, const authority& auth, bool is_trx_transient ) {
void authorization_manager::modify_permission( const permission_object& permission, const authority& auth ) {
for(const key_weight& k: auth.keys)
EOS_ASSERT(k.key.which() < _db.get<protocol_state_object>().num_supported_key_types, unactivated_key_type,
"Unactivated key type used when modifying permission");
_db.modify( permission, [&](permission_object& po) {
auto dm_logger = _control.get_deep_mind_logger(is_trx_transient);
auto dm_logger = _control.get_deep_mind_logger();
std::optional<permission_object> old_permission;
if (dm_logger) {
@@ -218,13 +216,13 @@ namespace eosio { namespace chain {
po.auth = auth;
po.last_updated = _control.pending_block_time();
if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) {
if (auto dm_logger = _control.get_deep_mind_logger()) {
dm_logger->on_modify_permission(*old_permission, po);
}
});
}
void authorization_manager::remove_permission( const permission_object& permission, bool is_trx_transient ) {
void authorization_manager::remove_permission( const permission_object& permission ) {
const auto& index = _db.template get_index<permission_index, by_parent>();
auto range = index.equal_range(permission.id);
EOS_ASSERT( range.first == range.second, action_validate_exception,
@@ -232,7 +230,7 @@ namespace eosio { namespace chain {
_db.get_mutable_index<permission_usage_index>().remove_object( permission.usage_id._id );
if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) {
if (auto dm_logger = _control.get_deep_mind_logger()) {
dm_logger->on_remove_permission(permission);
}
+1261 -1503
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -88,7 +88,7 @@ namespace eosio { namespace chain {
block_state::block_state( pending_block_header_state&& cur,
signed_block_ptr&& b,
deque<transaction_metadata_ptr>&& trx_metas,
vector<transaction_metadata_ptr>&& trx_metas,
const protocol_feature_set& pfs,
const std::function<void( block_timestamp_type,
const flat_set<digest_type>&,
File diff suppressed because it is too large Load Diff
-1
View File
@@ -42,7 +42,6 @@ namespace eosio::chain {
case deep_mind_handler::operation_qualifier::none: return "";
case deep_mind_handler::operation_qualifier::modify: return "MODIFY_";
case deep_mind_handler::operation_qualifier::push: return "PUSH_";
default: elog("Unknown operation_qualifier"); return "";
}
}
+15 -26
View File
@@ -54,7 +54,7 @@ void validate_authority_precondition( const apply_context& context, const author
}
}
if( context.trx_context.enforce_whiteblacklist && context.control.is_speculative_block() ) {
if( context.trx_context.enforce_whiteblacklist && context.control.is_producing_block() ) {
for( const auto& p : auth.keys ) {
context.control.check_key_list( p.key );
}
@@ -65,7 +65,6 @@ void validate_authority_precondition( const apply_context& context, const author
* This method is called assuming precondition_system_newaccount succeeds a
*/
void apply_eosio_newaccount(apply_context& context) {
EOS_ASSERT( !context.trx_context.is_read_only(), action_validate_exception, "newaccount not allowed in read-only transaction" );
auto create = context.get_action().data_as<newaccount>();
try {
context.require_authorization(create.creator);
@@ -108,18 +107,18 @@ void apply_eosio_newaccount(apply_context& context) {
}
const auto& owner_permission = authorization.create_permission( create.name, config::owner_name, 0,
std::move(create.owner), context.trx_context.is_transient() );
std::move(create.owner) );
const auto& active_permission = authorization.create_permission( create.name, config::active_name, owner_permission.id,
std::move(create.active), context.trx_context.is_transient() );
std::move(create.active) );
context.control.get_mutable_resource_limits_manager().initialize_account(create.name, context.trx_context.is_transient());
context.control.get_mutable_resource_limits_manager().initialize_account(create.name);
int64_t ram_delta = config::overhead_per_account_ram_bytes;
ram_delta += 2*config::billable_size_v<permission_object>;
ram_delta += owner_permission.auth.get_billable_size();
ram_delta += active_permission.auth.get_billable_size();
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
dm_logger->on_ram_trace(RAM_EVENT_ID("${name}", ("name", create.name)), "account", "add", "newaccount");
}
@@ -128,7 +127,6 @@ void apply_eosio_newaccount(apply_context& context) {
} FC_CAPTURE_AND_RETHROW( (create) ) }
void apply_eosio_setcode(apply_context& context) {
EOS_ASSERT( !context.trx_context.is_read_only(), action_validate_exception, "setcode not allowed in read-only transaction" );
auto& db = context.db;
auto act = context.get_action().data_as<setcode>();
context.require_authorization(act.account);
@@ -196,7 +194,7 @@ void apply_eosio_setcode(apply_context& context) {
});
if (new_size != old_size) {
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
const char* operation = "update";
if (old_size <= 0) {
operation = "add";
@@ -212,7 +210,6 @@ void apply_eosio_setcode(apply_context& context) {
}
void apply_eosio_setabi(apply_context& context) {
EOS_ASSERT( !context.trx_context.is_read_only(), action_validate_exception, "setabi ot allowed in read-only transaction" );
auto& db = context.db;
auto act = context.get_action().data_as<setabi>();
@@ -235,7 +232,7 @@ void apply_eosio_setabi(apply_context& context) {
});
if (new_size != old_size) {
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
const char* operation = "update";
if (old_size <= 0) {
operation = "add";
@@ -251,7 +248,6 @@ void apply_eosio_setabi(apply_context& context) {
}
void apply_eosio_updateauth(apply_context& context) {
EOS_ASSERT( !context.trx_context.is_read_only(), action_validate_exception, "updateauth not allowed in read-only transaction" );
auto update = context.get_action().data_as<updateauth>();
context.require_authorization(update.account); // only here to mark the single authority on this action as used
@@ -301,21 +297,21 @@ void apply_eosio_updateauth(apply_context& context) {
int64_t old_size = (int64_t)(config::billable_size_v<permission_object> + permission->auth.get_billable_size());
authorization.modify_permission( *permission, update.auth, context.trx_context.is_transient() );
authorization.modify_permission( *permission, update.auth );
int64_t new_size = (int64_t)(config::billable_size_v<permission_object> + permission->auth.get_billable_size());
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
dm_logger->on_ram_trace(RAM_EVENT_ID("${id}", ("id", permission->id)), "auth", "update", "updateauth_update");
}
context.add_ram_usage( permission->owner, new_size - old_size );
} else {
const auto& p = authorization.create_permission( update.account, update.permission, parent_id, update.auth, context.trx_context.is_transient() );
const auto& p = authorization.create_permission( update.account, update.permission, parent_id, update.auth );
int64_t new_size = (int64_t)(config::billable_size_v<permission_object> + p.auth.get_billable_size());
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
dm_logger->on_ram_trace(RAM_EVENT_ID("${id}", ("id", p.id)), "auth", "add", "updateauth_create");
}
@@ -326,8 +322,6 @@ void apply_eosio_updateauth(apply_context& context) {
void apply_eosio_deleteauth(apply_context& context) {
// context.require_write_lock( config::eosio_auth_scope );
EOS_ASSERT( !context.trx_context.is_read_only(), action_validate_exception, "deleteauth not allowed in read-only transaction" );
auto remove = context.get_action().data_as<deleteauth>();
context.require_authorization(remove.account); // only here to mark the single authority on this action as used
@@ -350,11 +344,11 @@ void apply_eosio_deleteauth(apply_context& context) {
const auto& permission = authorization.get_permission({remove.account, remove.permission});
int64_t old_size = config::billable_size_v<permission_object> + permission.auth.get_billable_size();
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
dm_logger->on_ram_trace(RAM_EVENT_ID("${id}", ("id", permission.id)), "auth", "remove", "deleteauth");
}
authorization.remove_permission( permission, context.trx_context.is_transient() );
authorization.remove_permission( permission );
context.add_ram_usage( remove.account, -old_size );
@@ -363,8 +357,6 @@ void apply_eosio_deleteauth(apply_context& context) {
void apply_eosio_linkauth(apply_context& context) {
// context.require_write_lock( config::eosio_auth_scope );
EOS_ASSERT( !context.trx_context.is_read_only(), action_validate_exception, "linkauth not allowed in read-only transaction" );
auto requirement = context.get_action().data_as<linkauth>();
try {
EOS_ASSERT(!requirement.requirement.empty(), action_validate_exception, "Required permission cannot be empty");
@@ -409,7 +401,7 @@ void apply_eosio_linkauth(apply_context& context) {
link.required_permission = requirement.requirement;
});
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
dm_logger->on_ram_trace(RAM_EVENT_ID("${id}", ("id", l.id)), "auth_link", "add", "linkauth");
}
@@ -425,8 +417,6 @@ void apply_eosio_linkauth(apply_context& context) {
void apply_eosio_unlinkauth(apply_context& context) {
// context.require_write_lock( config::eosio_auth_scope );
EOS_ASSERT( !context.trx_context.is_read_only(), action_validate_exception, "unlinkauth not allowed in read-only transaction" );
auto& db = context.db;
auto unlink = context.get_action().data_as<unlinkauth>();
@@ -436,7 +426,7 @@ void apply_eosio_unlinkauth(apply_context& context) {
auto link = db.find<permission_link_object, by_action_name>(link_key);
EOS_ASSERT(link != nullptr, action_validate_exception, "Attempting to unlink authority, but no link found");
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
dm_logger->on_ram_trace(RAM_EVENT_ID("${id}", ("id", link->id)), "auth_link", "remove", "unlinkauth");
}
@@ -449,7 +439,6 @@ void apply_eosio_unlinkauth(apply_context& context) {
}
void apply_eosio_canceldelay(apply_context& context) {
EOS_ASSERT( !context.trx_context.is_read_only(), action_validate_exception, "canceldelay not allowed in read-only transaction" );
auto cancel = context.get_action().data_as<canceldelay>();
context.require_authorization(cancel.canceling_auth.actor); // only here to mark the single authority on this action as used
@@ -35,17 +35,16 @@ struct abi_serializer {
using yield_function_t = fc::optional_delegate<void(size_t)>;
abi_serializer(){ configure_built_in_types(); }
abi_serializer( abi_def abi, const yield_function_t& yield );
abi_serializer( const abi_def& abi, const yield_function_t& yield );
[[deprecated("use the overload with yield_function_t[=create_yield_function(max_serialization_time)]")]]
abi_serializer( const abi_def& abi, const fc::microseconds& max_serialization_time );
void set_abi( abi_def abi, const yield_function_t& yield );
void set_abi( const abi_def& abi, const yield_function_t& yield );
[[deprecated("use the overload with yield_function_t[=create_yield_function(max_serialization_time)]")]]
void set_abi(const abi_def& abi, const fc::microseconds& max_serialization_time);
/// @return string_view of `t` or internal string type
std::string_view resolve_type(const std::string_view& t)const;
bool is_array(const std::string_view& type)const;
bool is_szarray(const std::string_view& type)const;
bool is_optional(const std::string_view& type)const;
bool is_type( const std::string_view& type, const yield_function_t& yield )const;
[[deprecated("use the overload with yield_function_t[=create_yield_function(max_serialization_time)]")]]
@@ -367,23 +366,6 @@ namespace impl {
mvo(name, std::move(array));
}
/**
* template which overloads add for deques of types which contain ABI information in their trees
* for these members we call ::add in order to trigger further processing
*/
template<typename M, typename Resolver, require_abi_t<M> = 1>
static void add( mutable_variant_object &mvo, const char* name, const deque<M>& v, Resolver resolver, abi_traverse_context& ctx )
{
auto h = ctx.enter_scope();
deque<fc::variant> array;
for (const auto& iter: v) {
mutable_variant_object elem_mvo;
add(elem_mvo, "_", iter, resolver, ctx);
array.emplace_back(std::move(elem_mvo["_"]));
}
mvo(name, std::move(array));
}
/**
* template which overloads add for shared_ptr of types which contain ABI information in their trees
* for these members we call ::add in order to trigger further processing
@@ -493,6 +475,7 @@ namespace impl {
binary_to_variant_context _ctx(*abi, ctx, type);
_ctx.short_path = true; // Just to be safe while avoiding the complexity of threading an override boolean all over the place
mvo( "data", abi->_binary_to_variant( type, act.data, _ctx ));
set_hex_data(mvo, "hex_data", act.data);
} catch(...) {
// any failure to serialize data, then leave as not serailzed
set_hex_data(mvo, "data", act.data);
@@ -506,7 +489,6 @@ namespace impl {
} catch(...) {
set_hex_data(mvo, "data", act.data);
}
set_hex_data(mvo, "hex_data", act.data);
out(name, std::move(mvo));
}
@@ -748,24 +730,6 @@ namespace impl {
}
}
/**
* template which overloads extract for deque of types which contain ABI information in their trees
* for these members we call ::extract in order to trigger further processing
*/
template<typename M, typename Resolver, require_abi_t<M> = 1>
static void extract( const fc::variant& v, deque<M>& o, Resolver resolver, abi_traverse_context& ctx )
{
auto h = ctx.enter_scope();
const variants& array = v.get_array();
o.clear();
for( auto itr = array.begin(); itr != array.end(); ++itr ) {
M o_iter;
extract(*itr, o_iter, resolver, ctx);
o.emplace_back(std::move(o_iter));
}
}
/**
* template which overloads extract for shared_ptr of types which contain ABI information in their trees
* for these members we call ::extract in order to trigger further processing
@@ -1,7 +1,6 @@
#pragma once
#include <eosio/chain/controller.hpp>
#include <eosio/chain/transaction.hpp>
#include <eosio/chain/transaction_context.hpp>
#include <eosio/chain/contract_table_objects.hpp>
#include <eosio/chain/deep_mind.hpp>
#include <fc/utility.hpp>
@@ -14,6 +13,7 @@ namespace chainbase { class database; }
namespace eosio { namespace chain {
class controller;
class transaction_context;
class apply_context {
private:
@@ -177,7 +177,6 @@ class apply_context {
int store( uint64_t scope, uint64_t table, const account_name& payer,
uint64_t id, secondary_key_proxy_const_type value )
{
EOS_ASSERT( !context.trx_context.is_read_only(), table_operation_not_permitted, "cannot store a db record when executing a readonly transaction" );
EOS_ASSERT( payer != account_name(), invalid_table_payer, "must specify a valid account to pay for new record" );
// context.require_write_lock( scope );
@@ -194,7 +193,7 @@ class apply_context {
context.db.modify( tab, [&]( auto& t ) {
++t.count;
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
std::string event_id = RAM_EVENT_ID("${code}:${scope}:${table}:${index_name}",
("code", t.code)
("scope", t.scope)
@@ -212,13 +211,12 @@ class apply_context {
}
void remove( int iterator ) {
EOS_ASSERT( !context.trx_context.is_read_only(), table_operation_not_permitted, "cannot remove a db record when executing a readonly transaction" );
const auto& obj = itr_cache.get( iterator );
const auto& table_obj = itr_cache.get_table( obj.t_id );
EOS_ASSERT( table_obj.code == context.receiver, table_access_violation, "db access violation" );
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient())) {
if (auto dm_logger = context.control.get_deep_mind_logger()) {
std::string event_id = RAM_EVENT_ID("${code}:${scope}:${table}:${index_name}",
("code", table_obj.code)
("scope", table_obj.scope)
@@ -245,7 +243,6 @@ class apply_context {
}
void update( int iterator, account_name payer, secondary_key_proxy_const_type secondary ) {
EOS_ASSERT( !context.trx_context.is_read_only(), table_operation_not_permitted, "cannot update a db record when executing a readonly transaction" );
const auto& obj = itr_cache.get( iterator );
const auto& table_obj = itr_cache.get_table( obj.t_id );
@@ -258,7 +255,7 @@ class apply_context {
int64_t billing_size = config::billable_size_v<ObjectType>;
std::string event_id;
if (context.control.get_deep_mind_logger(context.trx_context.is_transient()) != nullptr) {
if (context.control.get_deep_mind_logger() != nullptr) {
event_id = RAM_EVENT_ID("${code}:${scope}:${table}:${index_name}",
("code", table_obj.code)
("scope", table_obj.scope)
@@ -268,12 +265,12 @@ class apply_context {
}
if( obj.payer != payer ) {
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient()))
if (auto dm_logger = context.control.get_deep_mind_logger())
{
dm_logger->on_ram_trace(std::string(event_id), "secondary_index", "remove", "secondary_index_remove");
}
context.update_db_usage( obj.payer, -(billing_size) );
if (auto dm_logger = context.control.get_deep_mind_logger(context.trx_context.is_transient()))
if (auto dm_logger = context.control.get_deep_mind_logger())
{
dm_logger->on_ram_trace(std::move(event_id), "secondary_index", "add", "secondary_index_update_add_new_payer");
}
@@ -84,10 +84,6 @@ struct permission_level_weight {
friend bool operator == ( const permission_level_weight& lhs, const permission_level_weight& rhs ) {
return tie( lhs.permission, lhs.weight ) == tie( rhs.permission, rhs.weight );
}
friend bool operator < ( const permission_level_weight& lhs, const permission_level_weight& rhs ) {
return tie( lhs.permission, lhs.weight ) < tie( rhs.permission, rhs.weight );
}
};
struct key_weight {
@@ -97,10 +93,6 @@ struct key_weight {
friend bool operator == ( const key_weight& lhs, const key_weight& rhs ) {
return tie( lhs.key, lhs.weight ) == tie( rhs.key, rhs.weight );
}
friend bool operator < ( const key_weight& lhs, const key_weight& rhs ) {
return tie( lhs.key, lhs.weight ) < tie( rhs.key, rhs.weight );
}
};
@@ -145,10 +137,6 @@ struct wait_weight {
friend bool operator == ( const wait_weight& lhs, const wait_weight& rhs ) {
return tie( lhs.wait_sec, lhs.weight ) == tie( rhs.wait_sec, rhs.weight );
}
friend bool operator < ( const wait_weight& lhs, const wait_weight& rhs ) {
return tie( lhs.wait_sec, lhs.weight ) < tie( rhs.wait_sec, rhs.weight );
}
};
namespace config {
@@ -203,12 +191,6 @@ struct authority {
friend bool operator != ( const authority& lhs, const authority& rhs ) {
return tie( lhs.threshold, lhs.keys, lhs.accounts, lhs.waits ) != tie( rhs.threshold, rhs.keys, rhs.accounts, rhs.waits );
}
void sort_fields () {
std::sort(std::begin(keys), std::end(keys));
std::sort(std::begin(accounts), std::end(accounts));
std::sort(std::begin(waits), std::end(waits));
}
};
@@ -31,7 +31,6 @@ namespace eosio { namespace chain {
permission_name name,
permission_id_type parent,
const authority& auth,
bool is_trx_transient,
time_point initial_creation_time = time_point()
);
@@ -39,13 +38,12 @@ namespace eosio { namespace chain {
permission_name name,
permission_id_type parent,
authority&& auth,
bool is_trx_transient,
time_point initial_creation_time = time_point()
);
void modify_permission( const permission_object& permission, const authority& auth, bool is_trx_transient );
void modify_permission( const permission_object& permission, const authority& auth );
void remove_permission( const permission_object& permission, bool is_trx_transient );
void remove_permission( const permission_object& permission );
void update_permission_usage( const permission_object& permission );
@@ -97,7 +97,7 @@ namespace eosio { namespace chain {
signed_block& operator=(signed_block&&) = default;
signed_block clone() const { return *this; }
deque<transaction_receipt> transactions; /// new or generated transactions
vector<transaction_receipt> transactions; /// new or generated transactions
extensions_type block_extensions;
flat_multimap<uint16_t, block_extension> validate_and_extract_extensions()const;
@@ -2,11 +2,10 @@
#include <fc/filesystem.hpp>
#include <eosio/chain/block.hpp>
#include <eosio/chain/genesis_state.hpp>
#include <eosio/chain/block_log_config.hpp>
namespace eosio { namespace chain {
namespace detail { struct block_log_impl; }
namespace detail { class block_log_impl; }
/* The block log is an external append only log of the blocks with a header. Blocks should only
* be written to the log after they irreverisble as the log is append only. The log is a doubly
@@ -35,28 +34,29 @@ namespace eosio { namespace chain {
* An optional "pruned" mode can be activated which stores a 4 byte trailer on the log file indicating
* how many blocks at the end of the log are valid. Any earlier blocks in the log are assumed destroyed
* and unreadable due to reclamation for purposes of saving space.
*
* Object thread-safe. Not safe to have multiple block_log objects to same data_dir.
*/
struct block_log_prune_config {
uint32_t prune_blocks; //number of blocks to prune to when doing a prune
size_t prune_threshold = 4*1024*1024; //(approximately) how many bytes need to be added before a prune is performed
std::optional<size_t> vacuum_on_close; //when set, a vacuum is performed on dtor if log contains less than this many live bytes
};
class block_log {
public:
explicit block_log(const fc::path& data_dir, const block_log_config& config = block_log_config{});
block_log(block_log&& other) noexcept;
block_log(const fc::path& data_dir, std::optional<block_log_prune_config> prune_config);
block_log(block_log&& other);
~block_log();
void append(const signed_block_ptr& b, const block_id_type& id);
void append(const signed_block_ptr& b, const block_id_type& id, const std::vector<char>& packed_block);
void append(const signed_block_ptr& b);
void flush();
void reset( const genesis_state& gs, const signed_block_ptr& genesis_block );
void reset( const chain_id_type& chain_id, uint32_t first_block_num );
signed_block_ptr read_block(uint64_t file_pos)const;
void read_block_header(block_header& bh, uint64_t file_pos)const;
signed_block_ptr read_block_by_num(uint32_t block_num)const;
std::optional<signed_block_header> read_block_header_by_num(uint32_t block_num)const;
block_id_type read_block_id_by_num(uint32_t block_num)const;
signed_block_ptr read_block_by_id(const block_id_type& id)const {
return read_block_by_num(block_header::num_from_id(id));
}
@@ -64,11 +64,10 @@ namespace eosio { namespace chain {
/**
* Return offset of block in file, or block_log::npos if it does not exist.
*/
signed_block_ptr read_head()const; //use blocklog
signed_block_ptr head()const;
block_id_type head_id()const;
uint64_t get_block_pos(uint32_t block_num) const;
signed_block_ptr read_head()const;
const signed_block_ptr& head()const;
const block_id_type& head_id()const;
uint32_t first_block_num() const;
static const uint64_t npos = std::numeric_limits<uint64_t>::max();
@@ -76,10 +75,6 @@ namespace eosio { namespace chain {
static const uint32_t min_supported_version;
static const uint32_t max_supported_version;
/**
* All static methods expected to be called on quiescent block log
*/
static fc::path repair_log( const fc::path& data_dir, uint32_t truncate_at_block = 0, const char* reversible_block_dir_name="" );
static std::optional<genesis_state> extract_genesis_state( const fc::path& data_dir );
@@ -96,24 +91,36 @@ namespace eosio { namespace chain {
static bool is_pruned_log(const fc::path& data_dir);
static void extract_block_range(const fc::path& block_dir, const fc::path&output_dir, block_num_type start, block_num_type end);
static bool trim_blocklog_front(const fc::path& block_dir, const fc::path& temp_dir, uint32_t truncate_at_block);
static int trim_blocklog_end(const fc::path& block_dir, uint32_t n);
// used for unit test to generate older version blocklog
static void set_initial_version(uint32_t);
uint32_t version() const;
uint64_t get_block_pos(uint32_t block_num) const;
/**
* @param n Only test 1 block out of every n blocks. If n is 0, the interval is adjusted so that at most 8 blocks are tested.
*/
static void smoke_test(const fc::path& block_dir, uint32_t n);
static void split_blocklog(const fc::path& block_dir, const fc::path& dest_dir, uint32_t stride);
static void merge_blocklogs(const fc::path& block_dir, const fc::path& dest_dir);
private:
void open(const fc::path& data_dir);
void construct_index();
std::unique_ptr<detail::block_log_impl> my;
};
//to derive blknum_offset==14 see block_header.hpp and note on disk struct is packed
// block_timestamp_type timestamp; //bytes 0:3
// account_name producer; //bytes 4:11
// uint16_t confirmed; //bytes 12:13
// block_id_type previous; //bytes 14:45, low 4 bytes is big endian block number of previous block
struct trim_data { //used by trim_blocklog_front(), trim_blocklog_end(), and smoke_test()
trim_data(fc::path block_dir);
~trim_data();
uint64_t block_index(uint32_t n) const;
uint64_t block_pos(uint32_t n);
fc::path block_file_name, index_file_name; //full pathname for blocks.log and blocks.index
uint32_t version = 0; //blocklog version
uint32_t first_block = 0; //first block in blocks.log
uint32_t last_block = 0; //last block in blocks.log
FILE* blk_in = nullptr; //C style files for reading blocks.log and blocks.index
FILE* ind_in = nullptr; //C style files for reading blocks.log and blocks.index
//we use low level file IO because it is distinctly faster than C++ filebuf or iostream
uint64_t first_block_pos = 0; //file position in blocks.log for the first block in the log
chain_id_type chain_id;
static constexpr int blknum_offset{14}; //offset from start of block to 4 byte block number, valid for the only allowed versions
};
} }
@@ -1,31 +0,0 @@
#pragma once
#include <boost/filesystem/path.hpp>
#include <variant>
namespace eosio { namespace chain {
namespace bfs = boost::filesystem;
struct basic_blocklog_config {};
struct empty_blocklog_config {};
struct partitioned_blocklog_config {
bfs::path retained_dir;
bfs::path archive_dir;
uint32_t stride = UINT32_MAX;
uint32_t max_retained_files = UINT32_MAX;
};
struct prune_blocklog_config {
uint32_t prune_blocks; // number of blocks to prune to when doing a prune
size_t prune_threshold =
4 * 1024 * 1024; //(approximately) how many bytes need to be added before a prune is performed
std::optional<size_t>
vacuum_on_close; // when set, a vacuum is performed on dtor if log contains less than this many live bytes
};
using block_log_config =
std::variant<basic_blocklog_config, empty_blocklog_config, partitioned_blocklog_config, prune_blocklog_config>;
}} // namespace eosio::chain
@@ -19,7 +19,7 @@ namespace eosio { namespace chain {
block_state( pending_block_header_state&& cur,
signed_block_ptr&& b, // unsigned block
deque<transaction_metadata_ptr>&& trx_metas,
vector<transaction_metadata_ptr>&& trx_metas,
const protocol_feature_set& pfs,
const std::function<void( block_timestamp_type,
const flat_set<digest_type>&,
@@ -44,24 +44,24 @@ namespace eosio { namespace chain {
bool is_valid()const { return validated; }
bool is_pub_keys_recovered()const { return _pub_keys_recovered; }
deque<transaction_metadata_ptr> extract_trxs_metas() {
vector<transaction_metadata_ptr> extract_trxs_metas() {
_pub_keys_recovered = false;
auto result = std::move( _cached_trxs );
_cached_trxs.clear();
return result;
}
void set_trxs_metas( deque<transaction_metadata_ptr>&& trxs_metas, bool keys_recovered ) {
void set_trxs_metas( vector<transaction_metadata_ptr>&& trxs_metas, bool keys_recovered ) {
_pub_keys_recovered = keys_recovered;
_cached_trxs = std::move( trxs_metas );
}
const deque<transaction_metadata_ptr>& trxs_metas()const { return _cached_trxs; }
const vector<transaction_metadata_ptr>& trxs_metas()const { return _cached_trxs; }
bool validated = false;
bool _pub_keys_recovered = false;
/// this data is redundant with the data stored in block, but facilitates
/// recapturing transactions when we pop a block
deque<transaction_metadata_ptr> _cached_trxs;
vector<transaction_metadata_ptr> _cached_trxs;
};
using block_state_ptr = std::shared_ptr<block_state>;
@@ -37,10 +37,6 @@ namespace chain {
void reflector_init()const;
static chain_id_type empty_chain_id() {
return {};
}
private:
chain_id_type() = default;
@@ -48,7 +48,9 @@ namespace eosio { namespace chain {
class fork_database;
enum class db_read_mode {
SPECULATIVE,
HEAD,
READ_ONLY,
IRREVERSIBLE
};
@@ -68,7 +70,7 @@ namespace eosio { namespace chain {
flat_set< pair<account_name, action_name> > action_blacklist;
flat_set<public_key_type> key_blacklist;
path blocks_dir = chain::config::default_blocks_dir_name;
block_log_config blog;
std::optional<block_log_prune_config> prune_config;
path state_dir = chain::config::default_state_dir_name;
uint64_t state_size = chain::config::default_state_size;
uint64_t state_guard_size = chain::config::default_state_guard_size;
@@ -83,14 +85,12 @@ namespace eosio { namespace chain {
uint32_t maximum_variable_signature_length = chain::config::default_max_variable_signature_length;
bool disable_all_subjective_mitigations = false; //< for developer & testing purposes, can be configured using `disable-all-subjective-mitigations` when `EOSIO_DEVELOPER` build option is provided
uint32_t terminate_at_block = 0;
bool integrity_hash_on_start= false;
bool integrity_hash_on_stop = false;
wasm_interface::vm_type wasm_runtime = chain::config::default_wasm_runtime;
eosvmoc::config eosvmoc_config;
bool eosvmoc_tierup = false;
db_read_mode read_mode = db_read_mode::HEAD;
db_read_mode read_mode = db_read_mode::SPECULATIVE;
validation_mode block_validation_mode = validation_mode::FULL;
pinnable_mapped_file::map_mode db_map_mode = pinnable_mapped_file::map_mode::mapped;
@@ -106,8 +106,7 @@ namespace eosio { namespace chain {
irreversible = 0, ///< this block has already been applied before by this node and is considered irreversible
validated = 1, ///< this is a complete block signed by a valid producer and has been previously applied by this node and therefore validated but it is not yet irreversible
complete = 2, ///< this is a complete block signed by a valid producer but is not yet irreversible nor has it yet been applied by this node
incomplete = 3, ///< this is an incomplete block being produced by a producer
ephemeral = 4 ///< this is an incomplete block created for speculative execution of trxs, will always be aborted
incomplete = 3, ///< this is an incomplete block (either being produced by a producer or speculatively produced by a node)
};
controller( const config& cfg, const chain_id_type& chain_id );
@@ -119,25 +118,33 @@ namespace eosio { namespace chain {
void startup( std::function<void()> shutdown, std::function<bool()> check_shutdown, const genesis_state& genesis);
void startup( std::function<void()> shutdown, std::function<bool()> check_shutdown);
void preactivate_feature( const digest_type& feature_digest, bool is_trx_transient );
void preactivate_feature( const digest_type& feature_digest );
vector<digest_type> get_preactivated_protocol_features()const;
void validate_protocol_features( const vector<digest_type>& features_to_activate )const;
/**
* Starts a new pending block session upon which new transactions can be pushed.
* Starts a new pending block session upon which new transactions can
* be pushed.
*
* Will only activate protocol features that have been pre-activated.
*/
void start_block( block_timestamp_type time = block_timestamp_type(), uint16_t confirm_block_count = 0 );
/**
* Starts a new pending block session upon which new transactions can
* be pushed.
*/
void start_block( block_timestamp_type time,
uint16_t confirm_block_count,
const vector<digest_type>& new_protocol_feature_activations,
block_status bs,
const fc::time_point& deadline = fc::time_point::maximum() );
/**
* @return transactions applied in aborted block
*/
deque<transaction_metadata_ptr> abort_block();
vector<transaction_metadata_ptr> abort_block();
/**
*
@@ -155,14 +162,7 @@ namespace eosio { namespace chain {
fc::time_point block_deadline, fc::microseconds max_transaction_time,
uint32_t billed_cpu_time_us, bool explicit_billed_cpu_time );
struct block_report {
size_t total_net_usage = 0;
size_t total_cpu_usage_us = 0;
fc::microseconds total_elapsed_time{};
fc::microseconds total_time{};
};
block_state_ptr finalize_block( block_report& br, const signer_callback_type& signer_callback );
block_state_ptr finalize_block( const signer_callback_type& signer_callback );
void sign_block( const signer_callback_type& signer_callback );
void commit_block();
@@ -172,13 +172,11 @@ namespace eosio { namespace chain {
block_state_ptr create_block_state( const block_id_type& id, const signed_block_ptr& b ) const;
/**
* @param br returns statistics for block
* @param bsp block to push
* @param cb calls cb with forked applied transactions for each forked block
* @param trx_lookup user provided lookup function for externally cached transaction_metadata
*/
void push_block( block_report& br,
const block_state_ptr& bsp,
void push_block( const block_state_ptr& bsp,
const forked_branch_callback& cb,
const trx_meta_cache_lookup& trx_lookup );
@@ -221,6 +219,13 @@ namespace eosio { namespace chain {
uint32_t fork_db_head_block_num()const;
block_id_type fork_db_head_block_id()const;
time_point fork_db_head_block_time()const;
account_name fork_db_head_block_producer()const;
uint32_t fork_db_pending_head_block_num()const;
block_id_type fork_db_pending_head_block_id()const;
time_point fork_db_pending_head_block_time()const;
account_name fork_db_pending_head_block_producer()const;
time_point pending_block_time()const;
account_name pending_block_producer()const;
@@ -228,6 +233,8 @@ namespace eosio { namespace chain {
std::optional<block_id_type> pending_producer_block_id()const;
uint32_t pending_block_num()const;
const vector<transaction_receipt>& get_pending_trx_receipts()const;
const producer_authority_schedule& active_producers()const;
const producer_authority_schedule& pending_producers()const;
std::optional<producer_authority_schedule> proposed_producers()const;
@@ -236,19 +243,13 @@ namespace eosio { namespace chain {
block_id_type last_irreversible_block_id() const;
time_point last_irreversible_block_time() const;
// thread-safe
signed_block_ptr fetch_block_by_number( uint32_t block_num )const;
// thread-safe
signed_block_ptr fetch_block_by_id( const block_id_type& id )const;
// thread-safe
std::optional<signed_block_header> fetch_block_header_by_number( uint32_t block_num )const;
// thread-safe
std::optional<signed_block_header> fetch_block_header_by_id( const block_id_type& id )const;
// return block_state from forkdb, thread-safe
signed_block_ptr fetch_block_by_id( block_id_type id )const;
block_state_ptr fetch_block_state_by_number( uint32_t block_num )const;
// return block_state from forkdb, thread-safe
block_state_ptr fetch_block_state_by_id( block_id_type id )const;
// thread-safe
block_id_type get_block_id_for_num( uint32_t block_num )const;
sha256 calculate_integrity_hash();
@@ -260,7 +261,7 @@ namespace eosio { namespace chain {
void check_action_list( account_name code, action_name action )const;
void check_key_list( const public_key_type& key )const;
bool is_building_block()const;
bool is_speculative_block()const;
bool is_producing_block()const;
bool is_ram_billing_in_notify_allowed()const;
@@ -310,13 +311,12 @@ namespace eosio { namespace chain {
void add_to_ram_correction( account_name account, uint64_t ram_bytes );
bool all_subjective_mitigations_disabled()const;
deep_mind_handler* get_deep_mind_logger(bool is_trx_transient) const;
deep_mind_handler* get_deep_mind_logger() const;
void enable_deep_mind( deep_mind_handler* logger );
uint32_t earliest_available_block_num() const;
#if defined(EOSIO_EOS_VM_RUNTIME_ENABLED) || defined(EOSIO_EOS_VM_JIT_RUNTIME_ENABLED)
vm::wasm_allocator& get_wasm_allocator();
bool is_eos_vm_oc_enabled() const;
#endif
static std::optional<uint64_t> convert_exception_to_error_code( const fc::exception& e );
@@ -348,8 +348,9 @@ namespace eosio { namespace chain {
if( n.good() ) {
try {
const auto& a = get_account( n );
if( abi_def abi; abi_serializer::to_abi( a.abi, abi ))
return abi_serializer( std::move(abi), yield );
abi_def abi;
if( abi_serializer::to_abi( a.abi, abi ))
return abi_serializer( abi, yield );
} FC_CAPTURE_AND_LOG((n))
}
return std::optional<abi_serializer>();
@@ -370,10 +371,6 @@ namespace eosio { namespace chain {
void replace_producer_keys( const public_key_type& key );
void replace_account_keys( name account, name permission, const public_key_type& key );
void set_db_read_only_mode();
void unset_db_read_only_mode();
void init_thread_local_data();
private:
friend class apply_context;
friend class transaction_context;
@@ -186,6 +186,17 @@ namespace fc {
b = eosio::chain::shared_blob(_s.begin(), _s.end(), b.get_allocator());
}
inline
void to_variant( const blob& b, variant& v ) {
v = variant(base64_encode(b.data.data(), b.data.size()));
}
inline
void from_variant( const variant& v, blob& b ) {
string _s = base64_decode(v.as_string());
b.data = std::vector<char>(_s.begin(), _s.end());
}
template<typename T>
void to_variant( const eosio::chain::shared_vector<T>& sv, variant& v ) {
to_variant(std::vector<T>(sv.begin(), sv.end()), v);
@@ -573,12 +573,6 @@ namespace eosio { namespace chain {
3170011, "The signer returned no valid block signatures" )
FC_DECLARE_DERIVED_EXCEPTION( unsupported_multiple_block_signatures, producer_exception,
3170012, "The signer returned multiple signatures but that is not supported" )
FC_DECLARE_DERIVED_EXCEPTION( duplicate_snapshot_request, producer_exception,
3170013, "Snapshot has been already scheduled with specified parameters" )
FC_DECLARE_DERIVED_EXCEPTION( snapshot_request_not_found, producer_exception,
3170014, "Snapshot request not found" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_snapshot_request, producer_exception,
3170015, "Invalid snapshot request" )
FC_DECLARE_DERIVED_EXCEPTION( reversible_blocks_exception, chain_exception,
3180000, "Reversible Blocks exception" )
@@ -6,14 +6,11 @@
namespace eosio { namespace chain {
/**
* @brief limits for a kv database: NOT IN USE for mandel
* @brief limits for a kv database.
*
* Each database (ram or disk, currently) has its own limits for these parameters.
* The key and value limits apply when adding or modifying elements. They may be reduced
* below existing database entries.
*
* This has been marked for removal at a later date, when v7 snapshots are deemed necessary.
* kv_database_config will be removed as part of that effort.
*/
struct kv_database_config {
std::uint32_t max_key_size = 0; ///< the maximum size in bytes of a key
@@ -1,280 +0,0 @@
#pragma once
#include <boost/container/flat_map.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <fc/io/cfile.hpp>
#include <fc/io/datastream.hpp>
#include <regex>
namespace eosio {
namespace chain {
namespace bfs = boost::filesystem;
template <typename Lambda>
void for_each_file_in_dir_matches(const bfs::path& dir, std::string pattern, Lambda&& lambda) {
const std::regex my_filter(pattern);
std::smatch what;
bfs::directory_iterator end_itr; // Default ctor yields past-the-end
for (bfs::directory_iterator p(dir); p != end_itr; ++p) {
// Skip if not a file
if (!bfs::is_regular_file(p->status()))
continue;
// skip if it does not match the pattern
if (!std::regex_match(p->path().filename().string(), what, my_filter))
continue;
lambda(p->path());
}
}
struct null_verifier {
template <typename LogData>
void verify(const LogData&, const bfs::path&) {}
};
template <typename LogData, typename LogIndex, typename LogVerifier = null_verifier>
struct log_catalog {
using block_num_t = uint32_t;
struct mapped_type {
block_num_t last_block_num;
bfs::path filename_base;
};
using collection_t = boost::container::flat_map<block_num_t, mapped_type>;
using size_type = typename collection_t::size_type;
static constexpr size_type npos = std::numeric_limits<size_type>::max();
bfs::path retained_dir;
bfs::path archive_dir;
size_type max_retained_files = std::numeric_limits<size_type>::max();
collection_t collection;
size_type active_index = npos;
LogData log_data;
LogIndex log_index;
LogVerifier verifier;
bool empty() const { return collection.empty(); }
block_num_t first_block_num() const {
if (empty())
return std::numeric_limits<block_num_t>::max();
return collection.begin()->first;
}
block_num_t last_block_num() const {
if (empty())
return std::numeric_limits<block_num_t>::min();
return collection.rbegin()->second.last_block_num;
}
static bfs::path make_absolute_dir(const bfs::path& base_dir, bfs::path new_dir) {
if (new_dir.is_relative())
new_dir = base_dir / new_dir;
if (!bfs::is_directory(new_dir))
bfs::create_directories(new_dir);
return new_dir;
}
void open(const bfs::path& log_dir, const bfs::path& retained_path, const bfs::path& archive_path, const char* name,
const char* suffix_pattern = R"(-\d+-\d+\.log)") {
retained_dir = make_absolute_dir(log_dir, retained_path.empty() ? log_dir : retained_path);
if (!archive_path.empty()) {
archive_dir = make_absolute_dir(log_dir, archive_path);
}
for_each_file_in_dir_matches(retained_dir, std::string(name) + suffix_pattern, [this](bfs::path path) {
auto log_path = path;
auto index_path = path.replace_extension("index");
auto path_without_extension = log_path.parent_path() / log_path.stem().string();
LogData log(log_path);
verifier.verify(log, log_path);
// check if index file matches the log file
if (!index_matches_data(index_path, log))
log.construct_index(index_path);
auto existing_itr = collection.find(log.first_block_num());
if (existing_itr != collection.end()) {
if (log.last_block_num() <= existing_itr->second.last_block_num) {
wlog("${log_path} contains the overlapping range with ${existing_path}.log, dropping ${log_path} "
"from catalog",
("log_path", log_path.string())("existing_path", existing_itr->second.filename_base.string()));
return;
} else {
wlog(
"${log_path} contains the overlapping range with ${existing_path}.log, droping ${existing_path}.log "
"from catelog",
("log_path", log_path.string())("existing_path", existing_itr->second.filename_base.string()));
}
}
collection.insert_or_assign(log.first_block_num(), mapped_type{log.last_block_num(), path_without_extension});
});
}
bool index_matches_data(const bfs::path& index_path, LogData& log) const {
if (!bfs::exists(index_path))
return false;
auto num_blocks_in_index = bfs::file_size(index_path) / sizeof(uint64_t);
if (num_blocks_in_index != log.num_blocks())
return false;
// make sure the last 8 bytes of index and log matches
fc::cfile index_file;
index_file.set_file_path(index_path);
index_file.open("r");
index_file.seek_end(-sizeof(uint64_t));
uint64_t pos;
index_file.read(reinterpret_cast<char*>(&pos), sizeof(pos));
return pos == log.last_block_position();
}
std::optional<uint64_t> get_block_position(uint32_t block_num) {
try {
if (active_index != npos) {
auto active_item = collection.nth(active_index);
if (active_item->first <= block_num && block_num <= active_item->second.last_block_num) {
return log_index.nth_block_position(block_num - log_data.first_block_num());
}
}
if (block_num < first_block_num())
return {};
auto it = --collection.upper_bound(block_num);
if (block_num <= it->second.last_block_num) {
auto name = it->second.filename_base;
log_data.open(name.replace_extension("log"));
log_index.open(name.replace_extension("index"));
active_index = collection.index_of(it);
return log_index.nth_block_position(block_num - log_data.first_block_num());
}
return {};
} catch (...) {
active_index = npos;
return {};
}
}
fc::datastream<fc::cfile>* ro_stream_for_block(uint32_t block_num) {
auto pos = get_block_position(block_num);
if (pos) {
return &log_data.ro_stream_at(*pos);
}
return nullptr;
}
template <typename ...Rest>
auto ro_stream_for_block(uint32_t block_num, Rest&& ...rest) -> std::optional<decltype( std::declval<LogData>().ro_stream_at(0, std::forward<Rest&&>(rest)...))> {
auto pos = get_block_position(block_num);
if (pos) {
return log_data.ro_stream_at(*pos, std::forward<Rest&&>(rest)...);
}
return {};
}
std::optional<block_id_type> id_for_block(uint32_t block_num) {
auto pos = get_block_position(block_num);
if (pos) {
return log_data.block_id_at(*pos);
}
return {};
}
static void rename_if_not_exists(bfs::path old_name, bfs::path new_name) {
if (!bfs::exists(new_name)) {
bfs::rename(old_name, new_name);
} else {
bfs::remove(old_name);
wlog("${new_name} already exists, just removing ${old_name}",
("old_name", old_name.string())("new_name", new_name.string()));
}
}
static void rename_bundle(bfs::path orig_path, bfs::path new_path) {
rename_if_not_exists(orig_path.replace_extension(".log"), new_path.replace_extension(".log"));
rename_if_not_exists(orig_path.replace_extension(".index"), new_path.replace_extension(".index"));
}
/// Add a new entry into the catalog.
///
/// Notice that \c start_block_num must be monotonically increasing between the invocations of this function
/// so that the new entry would be inserted at the end of the flat_map; otherwise, \c active_index would be
/// invalidated and the mapping between the log data their block range would be wrong. This function is only used
/// during the splitting of block log. Using this function for other purpose should make sure if the monotonically
/// increasing block num guarantee can be met.
void add(uint32_t start_block_num, uint32_t end_block_num, const bfs::path& dir, const char* name) {
const int bufsize = 64;
char buf[bufsize];
snprintf(buf, bufsize, "%s-%u-%u", name, start_block_num, end_block_num);
bfs::path new_path = retained_dir / buf;
rename_bundle(dir / name, new_path);
size_type items_to_erase = 0;
collection.emplace(start_block_num, mapped_type{end_block_num, new_path});
if (collection.size() >= max_retained_files) {
items_to_erase =
max_retained_files > 0 ? collection.size() - max_retained_files : collection.size();
for (auto it = collection.begin(); it < collection.begin() + items_to_erase; ++it) {
auto orig_name = it->second.filename_base;
if (archive_dir.empty()) {
// delete the old files when no backup dir is specified
bfs::remove(orig_name.replace_extension("log"));
bfs::remove(orig_name.replace_extension("index"));
} else {
// move the the archive dir
rename_bundle(orig_name, archive_dir / orig_name.filename());
}
}
collection.erase(collection.begin(), collection.begin() + items_to_erase);
active_index = active_index == npos || active_index < items_to_erase
? npos
: active_index - items_to_erase;
}
}
/// Truncate the catalog so that the log/index bundle containing the block with \c block_num
/// would be rename to \c new_name; the log/index bundles with blocks strictly higher
/// than \c block_num would be deleted, and all the renamed/removed entries would be erased
/// from the catalog.
///
/// \return if nonzero, it's the starting block number for the log/index bundle being renamed.
uint32_t truncate(uint32_t block_num, bfs::path new_name) {
if (collection.empty())
return 0;
auto remove_files = [](typename collection_t::const_reference v) {
auto name = v.second.filename_base;
bfs::remove(name.replace_extension("log"));
bfs::remove(name.replace_extension("index"));
};
active_index = npos;
auto it = collection.upper_bound(block_num);
if (it == collection.begin() || block_num > (it - 1)->second.last_block_num) {
std::for_each(it, collection.end(), remove_files);
collection.erase(it, collection.end());
return 0;
} else {
auto truncate_it = --it;
auto name = truncate_it->second.filename_base;
bfs::rename(name.replace_extension("log"), new_name.replace_extension("log"));
bfs::rename(name.replace_extension("index"), new_name.replace_extension("index"));
std::for_each(truncate_it + 1, collection.end(), remove_files);
auto result = truncate_it->first;
collection.erase(truncate_it, collection.end());
return result;
}
}
};
} // namespace chain
} // namespace eosio
@@ -1,49 +0,0 @@
#pragma once
#include <fc/io/cfile.hpp>
namespace eosio {
namespace chain {
template <typename T>
T read_data_at(fc::datastream<fc::cfile>& file, std::size_t offset) {
file.seek(offset);
T value;
fc::raw::unpack(file, value);
return value;
}
template <typename Derived>
class log_data_base {
protected:
fc::datastream<fc::cfile> file;
Derived* self() { return static_cast<Derived*>(this); }
const Derived* self() const { return static_cast<const Derived*>(this); }
public:
log_data_base() = default;
void close() { file.close(); }
bool is_open() const { return file.is_open(); }
uint64_t size() const { return self()->size(); }
uint32_t last_block_num() { return self()->block_num_at(last_block_position()); }
uint64_t last_block_position() {
uint32_t offset = sizeof(uint64_t);
if (self()->is_currently_pruned())
offset += sizeof(uint32_t);
return read_data_at<uint64_t>(file, size() - offset);
}
uint32_t num_blocks() {
if (self()->first_block_position() == size())
return 0;
else if (self()->is_currently_pruned())
return read_data_at<uint32_t>(file, size() - sizeof(uint32_t));
return last_block_num() - self()->first_block_num() + 1;
}
};
} // namespace chain
} // namespace eosio
@@ -1,51 +0,0 @@
#pragma once
#include <boost/filesystem/path.hpp>
#include <fc/io/cfile.hpp>
namespace eosio {
namespace chain {
/// copy up to n bytes from the current position of src to dest
void copy_file_content(fc::cfile& src, fc::cfile& dest, uint64_t n = UINT64_MAX);
template <typename Exception>
class log_index {
fc::cfile file_;
std::size_t num_blocks_ = 0;
public:
log_index() = default;
log_index(const boost::filesystem::path& path) {
open(path);
}
void open(const boost::filesystem::path& path) {
if (file_.is_open())
file_.close();
file_.set_file_path(path);
file_.open("rb");
file_.seek_end(0);
num_blocks_ = file_.tellp()/ sizeof(uint64_t);
EOS_ASSERT(file_.tellp() % sizeof(uint64_t) == 0, Exception,
"The size of ${file} is not a multiple of sizeof(uint64_t)", ("file", path.generic_string()));
}
bool is_open() const { return file_.is_open(); }
uint64_t back() { return nth_block_position(num_blocks()-1); }
unsigned num_blocks() const { return num_blocks_; }
uint64_t nth_block_position(uint32_t n) {
file_.seek(n*sizeof(uint64_t));
uint64_t r;
file_.read((char*)&r, sizeof(r));
return r;
}
void copy_to(fc::cfile& dest, uint64_t nbytes) {
file_.seek(0);
copy_file_content(file_, dest, nbytes);
}
};
} // namespace chain
} // namespace eosio
@@ -17,6 +17,6 @@ namespace eosio { namespace chain {
/**
* Calculates the merkle root of a set of digests, if ids is odd it will duplicate the last id.
*/
digest_type merkle( deque<digest_type> ids );
digest_type merkle( vector<digest_type> ids );
} } /// eosio::chain
@@ -335,3 +335,4 @@ FC_REFLECT_DERIVED( eosio::chain::producer_schedule_change_extension, (eosio::ch
FC_REFLECT( eosio::chain::shared_block_signing_authority_v0, (threshold)(keys))
FC_REFLECT( eosio::chain::shared_producer_authority, (producer_name)(authority) )
FC_REFLECT( eosio::chain::shared_producer_authority_schedule, (version)(producers) )
@@ -264,7 +264,7 @@ protected:
class protocol_feature_manager {
public:
protocol_feature_manager( protocol_feature_set&& pfs, std::function<deep_mind_handler*(bool is_trx_transient)> get_deep_mind_logger );
protocol_feature_manager( protocol_feature_set&& pfs, std::function<deep_mind_handler*()> get_deep_mind_logger );
class const_iterator {
public:
@@ -393,12 +393,9 @@ protected:
bool _initialized = false;
private:
std::function<deep_mind_handler*(bool is_trx_transient)> _get_deep_mind_logger;
std::function<deep_mind_handler*()> _get_deep_mind_logger;
};
std::optional<builtin_protocol_feature> read_builtin_protocol_feature( const fc::path& p );
protocol_feature_set initialize_protocol_features( const fc::path& p, bool populate_missing_builtins = true );
} } // namespace eosio::chain
FC_REFLECT(eosio::chain::protocol_feature_subjective_restrictions,
@@ -4,7 +4,6 @@
#include <eosio/chain/config.hpp>
#include <eosio/chain/trace.hpp>
#include <eosio/chain/snapshot.hpp>
#include <eosio/chain/block_timestamp.hpp>
#include <chainbase/chainbase.hpp>
#include <set>
@@ -57,14 +56,12 @@ namespace eosio { namespace chain {
int64_t used = 0; ///< quantity used in current window
int64_t available = 0; ///< quantity available in current window (based upon fractional reserve)
int64_t max = 0; ///< max per window under current congestion
block_timestamp_type last_usage_update_time; ///< last usage timestamp
int64_t current_used = 0; ///< current usage according to the given timestamp
};
class resource_limits_manager {
public:
explicit resource_limits_manager(chainbase::database& db, std::function<deep_mind_handler*(bool is_trx_transient)> get_deep_mind_logger)
explicit resource_limits_manager(chainbase::database& db, std::function<deep_mind_handler*()> get_deep_mind_logger)
:_db(db),_get_deep_mind_logger(get_deep_mind_logger)
{
}
@@ -74,17 +71,17 @@ namespace eosio { namespace chain {
void add_to_snapshot( const snapshot_writer_ptr& snapshot ) const;
void read_from_snapshot( const snapshot_reader_ptr& snapshot );
void initialize_account( const account_name& account, bool is_trx_transient );
void initialize_account( const account_name& account );
void set_block_parameters( const elastic_limit_parameters& cpu_limit_parameters, const elastic_limit_parameters& net_limit_parameters );
void update_account_usage( const flat_set<account_name>& accounts, uint32_t ordinal );
void add_transaction_usage( const flat_set<account_name>& accounts, uint64_t cpu_usage, uint64_t net_usage, uint32_t ordinal, bool is_trx_transient = false );
void add_transaction_usage( const flat_set<account_name>& accounts, uint64_t cpu_usage, uint64_t net_usage, uint32_t ordinal );
void add_pending_ram_usage( const account_name account, int64_t ram_delta, bool is_trx_transient = false );
void add_pending_ram_usage( const account_name account, int64_t ram_delta );
void verify_account_ram_usage( const account_name accunt )const;
/// set_account_limits returns true if new ram_bytes limit is more restrictive than the previously set one
bool set_account_limits( const account_name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight, bool is_trx_transient);
bool set_account_limits( const account_name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight);
void get_account_limits( const account_name& account, int64_t& ram_bytes, int64_t& net_weight, int64_t& cpu_weight) const;
bool is_unlimited_cpu( const account_name& account ) const;
@@ -105,19 +102,17 @@ namespace eosio { namespace chain {
std::pair<int64_t, bool> get_account_cpu_limit( const account_name& name, uint32_t greylist_limit = config::maximum_elastic_resource_multiplier ) const;
std::pair<int64_t, bool> get_account_net_limit( const account_name& name, uint32_t greylist_limit = config::maximum_elastic_resource_multiplier ) const;
std::pair<account_resource_limit, bool>
get_account_cpu_limit_ex( const account_name& name, uint32_t greylist_limit = config::maximum_elastic_resource_multiplier, const std::optional<block_timestamp_type>& current_time={} ) const;
std::pair<account_resource_limit, bool>
get_account_net_limit_ex( const account_name& name, uint32_t greylist_limit = config::maximum_elastic_resource_multiplier, const std::optional<block_timestamp_type>& current_time={} ) const;
std::pair<account_resource_limit, bool> get_account_cpu_limit_ex( const account_name& name, uint32_t greylist_limit = config::maximum_elastic_resource_multiplier ) const;
std::pair<account_resource_limit, bool> get_account_net_limit_ex( const account_name& name, uint32_t greylist_limit = config::maximum_elastic_resource_multiplier ) const;
int64_t get_account_ram_usage( const account_name& name ) const;
private:
chainbase::database& _db;
std::function<deep_mind_handler*(bool is_trx_transient)> _get_deep_mind_logger;
std::function<deep_mind_handler*()> _get_deep_mind_logger;
};
} } } /// eosio::chain
FC_REFLECT( eosio::chain::resource_limits::account_resource_limit, (used)(available)(max)(last_usage_update_time)(current_used) )
FC_REFLECT( eosio::chain::resource_limits::account_resource_limit, (used)(available)(max) )
FC_REFLECT( eosio::chain::resource_limits::ratio, (numerator)(denominator))
FC_REFLECT( eosio::chain::resource_limits::elastic_limit_parameters, (target)(max)(periods)(max_multiplier)(contract_rate)(expand_rate))
@@ -5,7 +5,6 @@
#include <fc/variant_object.hpp>
#include <boost/core/demangle.hpp>
#include <ostream>
#include <memory>
namespace eosio { namespace chain {
/**
@@ -273,6 +272,11 @@ namespace eosio { namespace chain {
read_section(detail::snapshot_section_traits<T>::section_name(), f);
}
template<typename T>
bool has_section(const std::string& suffix = std::string()) {
return has_section(suffix + detail::snapshot_section_traits<T>::section_name());
}
virtual void validate() const = 0;
virtual void return_to_header() = 0;
@@ -280,6 +284,7 @@ namespace eosio { namespace chain {
virtual ~snapshot_reader(){};
protected:
virtual bool has_section( const std::string& section_name ) = 0;
virtual void set_section( const std::string& section_name ) = 0;
virtual bool read_row( detail::abstract_snapshot_row_reader& row_reader ) = 0;
virtual bool empty( ) = 0;
@@ -308,6 +313,7 @@ namespace eosio { namespace chain {
explicit variant_snapshot_reader(const fc::variant& snapshot);
void validate() const override;
bool has_section( const string& section_name ) override;
void set_section( const string& section_name ) override;
bool read_row( detail::abstract_snapshot_row_reader& row_reader ) override;
bool empty ( ) override;
@@ -336,22 +342,7 @@ namespace eosio { namespace chain {
std::streampos header_pos;
std::streampos section_pos;
uint64_t row_count;
};
class ostream_json_snapshot_writer : public snapshot_writer {
public:
explicit ostream_json_snapshot_writer(std::ostream& snapshot);
void write_start_section( const std::string& section_name ) override;
void write_row( const detail::abstract_snapshot_row_writer& row_writer ) override;
void write_end_section() override;
void finalize();
static const uint32_t magic_number = 0x30510550;
private:
detail::ostream_wrapper snapshot;
uint64_t row_count;
};
class istream_snapshot_reader : public snapshot_reader {
@@ -359,6 +350,7 @@ namespace eosio { namespace chain {
explicit istream_snapshot_reader(std::istream& snapshot);
void validate() const override;
bool has_section( const string& section_name ) override;
void set_section( const string& section_name ) override;
bool read_row( detail::abstract_snapshot_row_reader& row_reader ) override;
bool empty ( ) override;
@@ -374,24 +366,6 @@ namespace eosio { namespace chain {
uint64_t cur_row;
};
class istream_json_snapshot_reader : public snapshot_reader {
public:
explicit istream_json_snapshot_reader(const fc::path& p);
~istream_json_snapshot_reader();
void validate() const override;
void set_section( const string& section_name ) override;
bool read_row( detail::abstract_snapshot_row_reader& row_reader ) override;
bool empty ( ) override;
void clear_section() override;
void return_to_header() override;
private:
bool validate_section() const;
std::unique_ptr<struct istream_json_snapshot_reader_impl> impl;
};
class integrity_hash_snapshot_writer : public snapshot_writer {
public:
explicit integrity_hash_snapshot_writer(fc::sha256::encoder& enc);
@@ -165,25 +165,6 @@ namespace eosio {
return lhs.value() > rhs.value();
}
inline bool operator== (const extended_symbol& lhs, const extended_symbol& rhs)
{
return std::tie(lhs.sym, lhs.contract) == std::tie(rhs.sym, rhs.contract);
}
inline bool operator!= (const extended_symbol& lhs, const extended_symbol& rhs)
{
return std::tie(lhs.sym, lhs.contract) != std::tie(rhs.sym, rhs.contract);
}
inline bool operator< (const extended_symbol& lhs, const extended_symbol& rhs)
{
return std::tie(lhs.sym, lhs.contract) < std::tie(rhs.sym, rhs.contract);
}
inline bool operator> (const extended_symbol& lhs, const extended_symbol& rhs)
{
return std::tie(lhs.sym, lhs.contract) > std::tie(rhs.sym, rhs.contract);
}
} // namespace chain
} // namespace eosio
@@ -1,120 +1,46 @@
#pragma once
#include <eosio/chain/name.hpp>
#include <fc/exception/exception.hpp>
#include <fc/log/logger_config.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/asio/post.hpp>
#include <future>
#include <memory>
#include <optional>
#include <thread>
namespace eosio { namespace chain {
/**
* Wrapper class for thread pool of boost asio io_context run.
* Wrapper class for boost asio thread pool and io_context run.
* Also names threads so that tools like htop can see thread name.
* Example: named_thread_pool<struct net> thread_pool;
* or: struct net{}; named_thread_pool<net> thread_pool;
* @param NamePrefixTag is a type name appended with -## of thread.
* A short NamePrefixTag type name (6 chars or under) is recommended as console_appender uses
* 9 chars for the thread name.
*/
template<typename NamePrefixTag>
class named_thread_pool {
public:
using on_except_t = std::function<void(const fc::exception& e)>;
using init_t = std::function<void()>;
// name_prefix is name appended with -## of thread.
// short name_prefix (6 chars or under) is recommended as console_appender uses 9 chars for thread name
named_thread_pool( std::string name_prefix, size_t num_threads );
named_thread_pool() = default;
~named_thread_pool(){
stop();
}
// calls stop()
~named_thread_pool();
boost::asio::io_context& get_executor() { return _ioc; }
/// Spawn threads, can be re-started after stop().
/// Assumes start()/stop() called from the same thread or externally protected.
/// @param num_threads is number of threads spawned
/// @param on_except is the function to call if io_context throws an exception, is called from thread pool thread.
/// if an empty function then logs and rethrows exception on thread which will terminate.
/// @param init is an optional function to call at startup to initialize any data.
/// @throw assert_exception if already started and not stopped.
void start( size_t num_threads, on_except_t on_except, init_t init = {} ) {
FC_ASSERT( !_ioc_work, "Thread pool already started" );
_ioc_work.emplace( boost::asio::make_work_guard( _ioc ) );
_ioc.restart();
_thread_pool.reserve( num_threads );
for( size_t i = 0; i < num_threads; ++i ) {
_thread_pool.emplace_back( std::thread( &named_thread_pool::run_thread, this, i, on_except, init ) );
}
}
/// destroy work guard, stop io_context, join thread_pool
void stop() {
_ioc_work.reset();
_ioc.stop();
for( auto& t : _thread_pool ) {
t.join();
}
_thread_pool.clear();
}
private:
void run_thread( size_t i, const on_except_t& on_except, const init_t& init ) {
std::string tn = boost::core::demangle(typeid(this).name());
auto offset = tn.rfind("::");
if (offset != std::string::npos)
tn.erase(0, offset+2);
tn = tn.substr(0, tn.find('>')) + "-" + std::to_string( i );
try {
fc::set_os_thread_name( tn );
if ( init )
init();
_ioc.run();
} catch( const fc::exception& e ) {
if( on_except ) {
on_except( e );
} else {
elog( "Exiting thread ${t} on exception: ${e}", ("t", tn)("e", e.to_detail_string()) );
throw;
}
} catch( const std::exception& e ) {
fc::std_exception_wrapper se( FC_LOG_MESSAGE( warn, "${what}: ", ("what", e.what()) ),
std::current_exception(), BOOST_CORE_TYPEID( e ).name(), e.what() );
if( on_except ) {
on_except( se );
} else {
elog( "Exiting thread ${t} on exception: ${e}", ("t", tn)("e", se.to_detail_string()) );
throw;
}
} catch( ... ) {
if( on_except ) {
fc::unhandled_exception ue( FC_LOG_MESSAGE( warn, "unknown exception" ), std::current_exception() );
on_except( ue );
} else {
elog( "Exiting thread ${t} on unknown exception", ("t", tn) );
throw;
}
}
}
// destroy work guard, stop io_context, join thread_pool, and stop thread_pool
void stop();
private:
using ioc_work_t = boost::asio::executor_work_guard<boost::asio::io_context::executor_type>;
boost::asio::thread_pool _thread_pool;
boost::asio::io_context _ioc;
std::vector<std::thread> _thread_pool;
std::optional<ioc_work_t> _ioc_work;
};
// async on io_context and return future
// async on thread_pool and return future
template<typename F>
auto post_async_task( boost::asio::io_context& ioc, F&& f ) {
auto async_thread_pool( boost::asio::io_context& thread_pool, F&& f ) {
auto task = std::make_shared<std::packaged_task<decltype( f() )()>>( std::forward<F>( f ) );
boost::asio::post( ioc, [task]() { (*task)(); } );
boost::asio::post( thread_pool, [task]() { (*task)(); } );
return task->get_future();
}
@@ -49,6 +49,12 @@ namespace eosio { namespace chain {
* with a block_header::timestamp greater than expiration is
* deemed irreversible, then a user can safely trust the transaction
* will never be included.
*
* Each region is an independent blockchain, it is included as routing
* information for inter-blockchain communication. A contract in this
* region might generate or authorize a transaction intended for a foreign
* region.
*/
struct transaction_header {
time_point_sec expiration; ///< the time at which a transaction expires
@@ -70,7 +76,7 @@ namespace eosio { namespace chain {
};
/**
* A transaction consists of a set of messages which must all be applied or
* A transaction consits of a set of messages which must all be applied or
* all are rejected. These messages have access to data within the given
* read and write scopes.
*/
@@ -39,7 +39,7 @@ namespace eosio { namespace chain {
const packed_transaction& t,
transaction_checktime_timer&& timer,
fc::time_point start = fc::time_point::now(),
transaction_metadata::trx_type type = transaction_metadata::trx_type::input);
bool read_only=false);
~transaction_context();
void init_for_implicit_trx( uint64_t initial_net_usage = 0 );
@@ -83,10 +83,6 @@ namespace eosio { namespace chain {
void validate_referenced_accounts( const transaction& trx, bool enforce_actor_whitelist_blacklist )const;
bool is_dry_run()const { return trx_type == transaction_metadata::trx_type::dry_run; };
bool is_read_only()const { return trx_type == transaction_metadata::trx_type::read_only; };
bool is_transient()const { return trx_type == transaction_metadata::trx_type::read_only || trx_type == transaction_metadata::trx_type::dry_run; };
private:
friend struct controller_impl;
@@ -114,14 +110,12 @@ namespace eosio { namespace chain {
void schedule_transaction();
void record_transaction( const transaction_id_type& id, fc::time_point_sec expire );
void validate_cpu_usage_to_bill( int64_t billed_us, int64_t account_cpu_limit, bool check_minimum, int64_t subjective_billed_us )const;
void validate_account_cpu_usage( int64_t billed_us, int64_t account_cpu_limit, int64_t subjective_billed_us )const;
void validate_account_cpu_usage_estimate( int64_t billed_us, int64_t account_cpu_limit, int64_t subjective_billed_us )const;
void validate_cpu_usage_to_bill( int64_t billed_us, int64_t account_cpu_limit, bool check_minimum )const;
void validate_account_cpu_usage( int64_t billed_us, int64_t account_cpu_limit )const;
void validate_account_cpu_usage_estimate( int64_t billed_us, int64_t account_cpu_limit )const;
void disallow_transaction_extensions( const char* error_msg )const;
std::string get_tx_cpu_usage_exceeded_reason_msg(fc::microseconds& limit) const;
/// Fields:
public:
@@ -134,7 +128,7 @@ namespace eosio { namespace chain {
fc::time_point published;
deque<digest_type> executed_action_receipt_digests;
vector<digest_type> executed_action_receipt_digests;
flat_set<account_name> bill_to_accounts;
flat_set<account_name> validate_ram_usage;
@@ -154,9 +148,9 @@ namespace eosio { namespace chain {
transaction_checktime_timer transaction_timer;
const bool is_read_only;
private:
bool is_initialized = false;
transaction_metadata::trx_type trx_type;
uint64_t net_limit = 0;
bool net_limit_due_to_block = true;
@@ -175,16 +169,6 @@ namespace eosio { namespace chain {
int64_t billing_timer_exception_code = block_cpu_usage_exceeded::code_value;
fc::time_point pseudo_start;
fc::microseconds billed_time;
enum class tx_cpu_usage_exceeded_reason {
account_cpu_limit, // includes subjective billing
on_chain_consensus_max_transaction_cpu_usage,
user_specified_trx_max_cpu_usage_ms,
node_configured_max_transaction_time,
speculative_executed_adjusted_max_transaction_time // prev_billed_cpu_time_us > 0
};
tx_cpu_usage_exceeded_reason tx_cpu_usage_reason = tx_cpu_usage_exceeded_reason::account_cpu_limit;
fc::microseconds tx_cpu_usage_amount;
};
} }
@@ -24,7 +24,6 @@ class transaction_metadata {
input,
implicit,
scheduled,
dry_run,
read_only
};
@@ -32,9 +31,11 @@ class transaction_metadata {
const packed_transaction_ptr _packed_trx;
const fc::microseconds _sig_cpu_usage;
const flat_set<public_key_type> _recovered_pub_keys;
const trx_type _trx_type;
public:
const bool implicit;
const bool scheduled;
const bool read_only;
bool accepted = false; // not thread safe
uint32_t billed_cpu_time_us = 0; // not thread safe
@@ -51,11 +52,13 @@ class transaction_metadata {
// creation of tranaction_metadata restricted to start_recover_keys and create_no_recover_keys below, public for make_shared
explicit transaction_metadata( const private_type& pt, packed_transaction_ptr ptrx,
fc::microseconds sig_cpu_usage, flat_set<public_key_type> recovered_pub_keys,
trx_type t = trx_type::input )
bool _implicit = false, bool _scheduled = false, bool _read_only = false)
: _packed_trx( std::move( ptrx ) )
, _sig_cpu_usage( sig_cpu_usage )
, _recovered_pub_keys( std::move( recovered_pub_keys ) )
, _trx_type( t ) {
, implicit( _implicit )
, scheduled( _scheduled )
, read_only( _read_only) {
}
transaction_metadata() = delete;
@@ -70,12 +73,6 @@ class transaction_metadata {
fc::microseconds signature_cpu_usage()const { return _sig_cpu_usage; }
const flat_set<public_key_type>& recovered_keys()const { return _recovered_pub_keys; }
size_t get_estimated_size() const;
trx_type get_trx_type() const { return _trx_type; };
bool implicit() const { return _trx_type == trx_type::implicit; };
bool scheduled() const { return _trx_type == trx_type::scheduled; };
bool is_dry_run() const { return _trx_type == trx_type::dry_run; };
bool is_read_only() const { return _trx_type == trx_type::read_only; };
bool is_transient() const { return _trx_type == trx_type::read_only || _trx_type == trx_type::dry_run; };
/// Thread safe.
/// @returns transaction_metadata_ptr or exception via future
@@ -88,7 +85,7 @@ class transaction_metadata {
static transaction_metadata_ptr
create_no_recover_keys( packed_transaction_ptr trx, trx_type t ) {
return std::make_shared<transaction_metadata>( private_type(), std::move(trx),
fc::microseconds(), flat_set<public_key_type>(), t );
fc::microseconds(), flat_set<public_key_type>(), t == trx_type::implicit, t == trx_type::scheduled, t==trx_type::read_only );
}
};
+2 -13
View File
@@ -17,9 +17,6 @@
#include <fc/fixed_string.hpp>
#include <fc/crypto/private_key.hpp>
#include <boost/version.hpp>
#include <boost/container/deque.hpp>
#include <memory>
#include <vector>
#include <deque>
@@ -48,6 +45,7 @@ namespace eosio { namespace chain {
using std::vector;
using std::unordered_map;
using std::string;
using std::deque;
using std::shared_ptr;
using std::weak_ptr;
using std::unique_ptr;
@@ -78,15 +76,7 @@ namespace eosio { namespace chain {
using public_key_type = fc::crypto::public_key;
using private_key_type = fc::crypto::private_key;
using signature_type = fc::crypto::signature;
#if BOOST_VERSION >= 107100
// configurable boost deque performs much better than std::deque in our use cases
using block_1024_option_t = boost::container::deque_options< boost::container::block_size<1024u> >::type;
template<typename T>
using deque = boost::container::deque< T, void, block_1024_option_t >;
#else
template<typename T>
using deque = std::deque<T>;
#endif
struct void_t{};
using chainbase::allocator;
@@ -251,7 +241,6 @@ namespace eosio { namespace chain {
using int128_t = __int128;
using uint128_t = unsigned __int128;
using bytes = vector<char>;
using digests_t = deque<digest_type>;
struct sha256_less {
bool operator()( const fc::sha256& lhs, const fc::sha256& rhs ) const {
@@ -21,22 +21,23 @@ using namespace boost::multi_index;
enum class trx_enum_type {
unknown = 0,
forked = 1,
aborted = 2,
incoming_api = 3,
incoming_p2p = 4 // incoming_end() needs to be updated if this changes
persisted = 1,
forked = 2,
aborted = 3,
incoming_persisted = 4,
incoming = 5 // incoming_end() needs to be updated if this changes
};
using next_func_t = std::function<void(const std::variant<fc::exception_ptr, transaction_trace_ptr>&)>;
struct unapplied_transaction {
const transaction_metadata_ptr trx_meta;
const fc::time_point expiry;
trx_enum_type trx_type = trx_enum_type::unknown;
bool return_failure_trace = false;
next_func_t next;
const transaction_id_type& id()const { return trx_meta->id(); }
fc::time_point_sec expiration()const { return trx_meta->packed_trx()->expiration(); }
unapplied_transaction(const unapplied_transaction&) = delete;
unapplied_transaction() = delete;
@@ -45,7 +46,8 @@ struct unapplied_transaction {
};
/**
* Track unapplied transactions for incoming, forked blocks, and aborted blocks.
* Track unapplied transactions for persisted, forked blocks, and aborted blocks.
* Persisted are first so that they can be applied in each block until expired.
*/
class unapplied_transaction_queue {
private:
@@ -59,7 +61,7 @@ private:
const_mem_fun<unapplied_transaction, const transaction_id_type&, &unapplied_transaction::id>
>,
ordered_non_unique< tag<by_type>, member<unapplied_transaction, trx_enum_type, &unapplied_transaction::trx_type> >,
ordered_non_unique< tag<by_expiry>, const_mem_fun<unapplied_transaction, fc::time_point_sec, &unapplied_transaction::expiration> >
ordered_non_unique< tag<by_expiry>, member<unapplied_transaction, const fc::time_point, &unapplied_transaction::expiry> >
>
> unapplied_trx_queue_type;
@@ -99,7 +101,7 @@ public:
auto& persisted_by_expiry = queue.get<by_expiry>();
while( !persisted_by_expiry.empty() ) {
const auto& itr = persisted_by_expiry.begin();
if( itr->expiration() > pending_block_time ) {
if( itr->expiry > pending_block_time ) {
break;
}
if( yield() ) {
@@ -144,24 +146,42 @@ public:
const block_state_ptr& bsptr = *ritr;
for( auto itr = bsptr->trxs_metas().begin(), end = bsptr->trxs_metas().end(); itr != end; ++itr ) {
const auto& trx = *itr;
auto insert_itr = queue.insert( { trx, trx_enum_type::forked } );
fc::time_point expiry = trx->packed_trx()->expiration();
auto insert_itr = queue.insert( { trx, expiry, trx_enum_type::forked } );
if( insert_itr.second ) added( insert_itr.first );
}
}
}
void add_aborted( deque<transaction_metadata_ptr> aborted_trxs ) {
void add_aborted( std::vector<transaction_metadata_ptr> aborted_trxs ) {
for( auto& trx : aborted_trxs ) {
auto insert_itr = queue.insert( { std::move( trx ), trx_enum_type::aborted } );
fc::time_point expiry = trx->packed_trx()->expiration();
auto insert_itr = queue.insert( { std::move( trx ), expiry, trx_enum_type::aborted } );
if( insert_itr.second ) added( insert_itr.first );
}
}
void add_incoming( const transaction_metadata_ptr& trx, bool api_trx, bool return_failure_trace, next_func_t next ) {
void add_persisted( const transaction_metadata_ptr& trx ) {
auto itr = queue.get<by_trx_id>().find( trx->id() );
if( itr == queue.get<by_trx_id>().end() ) {
fc::time_point expiry = trx->packed_trx()->expiration();
auto insert_itr = queue.insert( { trx, expiry, trx_enum_type::persisted } );
if( insert_itr.second ) added( insert_itr.first );
} else if( itr->trx_type != trx_enum_type::persisted ) {
if (itr->trx_type == trx_enum_type::incoming || itr->trx_type == trx_enum_type::incoming_persisted)
--incoming_count;
queue.get<by_trx_id>().modify( itr, [](auto& un){
un.trx_type = trx_enum_type::persisted;
} );
}
}
void add_incoming( const transaction_metadata_ptr& trx, bool persist_until_expired, bool return_failure_trace, next_func_t next ) {
auto itr = queue.get<by_trx_id>().find( trx->id() );
if( itr == queue.get<by_trx_id>().end() ) {
fc::time_point expiry = trx->packed_trx()->expiration();
auto insert_itr = queue.insert(
{ trx, api_trx ? trx_enum_type::incoming_api : trx_enum_type::incoming_p2p, return_failure_trace, std::move( next ) } );
{ trx, expiry, persist_until_expired ? trx_enum_type::incoming_persisted : trx_enum_type::incoming, return_failure_trace, std::move( next ) } );
if( insert_itr.second ) added( insert_itr.first );
} else {
if( itr->trx_meta == trx ) return; // same trx meta pointer
@@ -177,18 +197,15 @@ public:
iterator begin() { return queue.get<by_type>().begin(); }
iterator end() { return queue.get<by_type>().end(); }
// forked, aborted
// persisted, forked, aborted
iterator unapplied_begin() { return queue.get<by_type>().begin(); }
iterator unapplied_end() { return queue.get<by_type>().upper_bound( trx_enum_type::aborted ); }
iterator incoming_begin() { return queue.get<by_type>().lower_bound( trx_enum_type::incoming_api ); }
iterator incoming_end() { return queue.get<by_type>().end(); } // if changed to upper_bound, verify usage performance
iterator persisted_begin() { return queue.get<by_type>().lower_bound( trx_enum_type::persisted ); }
iterator persisted_end() { return queue.get<by_type>().upper_bound( trx_enum_type::persisted ); }
iterator lower_bound( const transaction_id_type& id ) {
auto itr = queue.get<by_trx_id>().find( id );
if( itr == queue.get<by_trx_id>().end() ) return queue.get<by_type>().end();
return queue.project<by_type>(itr);
}
iterator incoming_begin() { return queue.get<by_type>().lower_bound( trx_enum_type::incoming_persisted ); }
iterator incoming_end() { return queue.get<by_type>().end(); } // if changed to upper_bound, verify usage performance
/// caller's responsibility to call next() if applicable
iterator erase( iterator itr ) {
@@ -200,7 +217,7 @@ private:
template<typename Itr>
void added( Itr itr ) {
auto size = calc_size( itr->trx_meta );
if( itr->trx_type == trx_enum_type::incoming_p2p || itr->trx_type == trx_enum_type::incoming_api ) {
if( itr->trx_type == trx_enum_type::incoming || itr->trx_type == trx_enum_type::incoming_persisted ) {
++incoming_count;
EOS_ASSERT( size_in_bytes + size < max_transaction_queue_size, tx_resource_exhaustion,
"Transaction ${id}, size ${s} bytes would exceed configured "
@@ -213,7 +230,7 @@ private:
template<typename Itr>
void removed( Itr itr ) {
if( itr->trx_type == trx_enum_type::incoming_p2p || itr->trx_type == trx_enum_type::incoming_api ) {
if( itr->trx_type == trx_enum_type::incoming || itr->trx_type == trx_enum_type::incoming_persisted ) {
--incoming_count;
}
size_in_bytes -= calc_size( itr->trx_meta );
@@ -332,7 +332,7 @@ namespace eosio { namespace chain { namespace wasm_validations {
public:
wasm_binary_validation( const eosio::chain::controller& control, IR::Module& mod ) : _module( &mod ) {
// initialize validators here
nested_validator::init(!control.is_speculative_block());
nested_validator::init(!control.is_producing_block());
}
void validate() {
@@ -45,9 +45,6 @@ namespace eosio { namespace chain {
wasm_interface(vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile);
~wasm_interface();
// initialize exec per thread
void init_thread_local_data();
//call before dtor to skip what can be minutes of dtor overhead with some runtimes; can cause leaks
void indicate_shutting_down();
@@ -66,16 +63,12 @@ namespace eosio { namespace chain {
//Immediately exits currently running wasm. UB is called when no wasm running
void exit();
//Returns true if the code is cached
bool is_code_cached(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version) const;
// If substitute_apply is set, then apply calls it before doing anything else. If substitute_apply returns true,
// then apply returns immediately.
std::function<bool(
const digest_type& code_hash, uint8_t vm_type, uint8_t vm_version, apply_context& context)> substitute_apply;
private:
unique_ptr<struct wasm_interface_impl> my;
vm_type vm;
};
} } // eosio::chain
@@ -50,21 +50,11 @@ namespace eosio { namespace chain {
#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
struct eosvmoc_tier {
eosvmoc_tier(const boost::filesystem::path& d, const eosvmoc::config& c, const chainbase::database& db)
: cc(d, c, db) {
// construct exec for the main thread
init_thread_local_data();
}
// Support multi-threaded execution.
void init_thread_local_data() {
exec = std::make_unique<eosvmoc::executor>(cc);
}
: cc(d, c, db), exec(cc),
mem(wasm_constraints::maximum_linear_memory/wasm_constraints::wasm_page_size) {}
eosvmoc::code_cache_async cc;
// Each thread requires its own exec and mem. Defined in wasm_interface.cpp
thread_local static std::unique_ptr<eosvmoc::executor> exec;
thread_local static eosvmoc::memory mem;
eosvmoc::executor exec;
eosvmoc::memory mem;
};
#endif
@@ -104,11 +94,6 @@ namespace eosio { namespace chain {
});
}
bool is_code_cached(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version) const {
wasm_cache_index::iterator it = wasm_instantiation_cache.find( boost::make_tuple(code_hash, vm_type, vm_version) );
return it != wasm_instantiation_cache.end();
}
std::vector<uint8_t> parse_initial_memory(const Module& module) {
std::vector<uint8_t> mem_image;
@@ -1,7 +1,6 @@
#pragma once
#include <vector>
#include <string>
#include <stdint.h>
namespace eosio { namespace chain {
@@ -34,16 +34,11 @@ class eosvmoc_runtime : public eosio::chain::wasm_runtime_interface {
const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version) override;
void immediately_exit_currently_running_module() override;
void init_thread_local_data() override;
friend eosvmoc_instantiated_module;
eosvmoc::code_cache_sync cc;
eosvmoc::executor exec;
eosvmoc::memory mem;
// Defined in eos-vm-oc.cpp. Used for non-main thread in multi-threaded execution
thread_local static std::unique_ptr<eosvmoc::executor> exec_thread_local;
thread_local static eosvmoc::memory mem_thread_local;
};
/**
@@ -354,13 +349,7 @@ auto fn(A... a) {
: "cc");
}
using native_args = vm::flatten_parameters_t<AUTO_PARAM_WORKAROUND(F)>;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value"
// If a is unpopulated, this reports "statement has no effect [-Werror=unused-value]"
eosio::vm::native_value stack[] = { a... };
#pragma GCC diagnostic pop
constexpr int cb_ctx_ptr_offset = OFFSET_OF_CONTROL_BLOCK_MEMBER(ctx);
apply_context* ctx;
asm("mov %%gs:%c[applyContextOffset], %[cPtr]\n"
@@ -396,7 +385,7 @@ void register_eosvm_oc(Name n) {
if(n == BOOST_HANA_STRING("env.eosio_exit")) return;
constexpr auto fn = create_function<F, Preconditions, injected>();
constexpr auto index = find_intrinsic_index(n.c_str());
[[maybe_unused]] intrinsic the_intrinsic(
intrinsic the_intrinsic(
n.c_str(),
wasm_function_type_provider<std::remove_pointer_t<decltype(fn)>>::type(),
reinterpret_cast<void*>(fn),
@@ -15,7 +15,6 @@
#include <thread>
#include <shared_mutex>
namespace std {
template<> struct hash<eosio::chain::eosvmoc::code_tuple> {
@@ -85,9 +84,6 @@ class code_cache_base {
template <typename T>
void serialize_cache_index(fc::datastream<T>& ds);
std::thread::id _main_thread_id;
bool is_main_thread() const;
};
class code_cache_async : public code_cache_base {
@@ -118,4 +114,4 @@ class code_cache_sync : public code_cache_base {
const code_descriptor* const get_descriptor_for_code_sync(const digest_type& code_id, const uint8_t& vm_version);
};
}}}
}}}
@@ -50,9 +50,7 @@ class memory {
// The maximum amount of data that PIC code can include in the prologue
static constexpr uintptr_t max_prologue_size = mutable_global_size + table_size;
// Changed from -cb_offset == EOS_VM_OC_CONTROL_BLOCK_OFFSET to get around
// of compile warning about comparing integers of different signedness
static_assert(EOS_VM_OC_CONTROL_BLOCK_OFFSET + cb_offset == 0, "EOS VM OC control block offset has slid out of place somehow");
static_assert(-cb_offset == EOS_VM_OC_CONTROL_BLOCK_OFFSET, "EOS VM OC control block offset has slid out of place somehow");
static_assert(stride == EOS_VM_OC_MEMORY_STRIDE, "EOS VM OC memory stride has slid out of place somehow");
private:
@@ -844,7 +844,7 @@ namespace webassembly {
/**
* Find the table row in a primary 64-bit integer index table that matches the lowerbound condition for a given primary key.
* Lowerbound record is the first nearest record which primary key is >= the given key.
* Lowerbound record is the first nearest record which primary key is <= the given key.
*
* @ingroup database primary-index
* @param code - the name of the owner of the table.
@@ -954,7 +954,7 @@ namespace webassembly {
/**
* Find the table row in a secondary 64-bit integer index table that matches the lowerbound condition for a given secondary key.
* Lowerbound secondary index is the first secondary index which key is >= the given secondary index key.
* Lowerbound secondary index is the first secondary index which key is <= the given secondary index key.
*
* @ingroup database uint64_t-secondary-index
* @param code - the name of the owner of the table.
@@ -1095,7 +1095,7 @@ namespace webassembly {
/**
* Find the table row in a secondary 128-bit integer index table that matches the lowerbound condition for a given secondary key.
* Lowerbound secondary index is the first secondary index which key is >= the given secondary index key.
* Lowerbound secondary index is the first secondary index which key is <= the given secondary index key.
*
* @ingroup database uint128_t-secondary-index
* @param code - the name of the owner of the table.
@@ -1236,7 +1236,7 @@ namespace webassembly {
/**
* Find the table row in a secondary 256-bit integer index table that matches the lowerbound condition for a given secondary key.
* Lowerbound secondary index is the first secondary index which key is >= the given secondary index key.
* Lowerbound secondary index is the first secondary index which key is <= the given secondary index key.
*
* @ingroup database 256-bit-secondary-index
* @param code - the name of the owner of the table.
@@ -1380,7 +1380,7 @@ namespace webassembly {
/**
* Find the table row in a secondary double-precision floating-point index table that matches the lowerbound condition for a given secondary key.
* Lowerbound secondary index is the first secondary index which key is >= the given secondary index key.
* Lowerbound secondary index is the first secondary index which key is <= the given secondary index key.
*
* @ingroup database double-secondary-index
* @param code - the name of the owner of the table.
@@ -1524,7 +1524,7 @@ namespace webassembly {
/**
* Find the table row in a secondary quadruple-precision floating-point index table that matches the lowerbound condition for a given secondary key.
* Lowerbound secondary index is the first secondary index which key is >= the given secondary index key.
* Lowerbound secondary index is the first secondary index which key is <= the given secondary index key.
*
* @ingroup database long-double-secondary-index
* @param code - the name of the owner of the table.
@@ -27,9 +27,6 @@ class wasm_runtime_interface {
virtual void immediately_exit_currently_running_module() = 0;
virtual ~wasm_runtime_interface();
// eosvmoc_runtime needs this
virtual void init_thread_local_data() {};
};
}}
+1 -1
View File
@@ -32,7 +32,7 @@ bool is_canonical_right(const digest_type& val) {
}
digest_type merkle(deque<digest_type> ids) {
digest_type merkle(vector<digest_type> ids) {
if( 0 == ids.size() ) { return digest_type(); }
while( ids.size() > 1 ) {
View File
@@ -28,7 +28,6 @@ platform_timer::platform_timer() {
if(refcount++ == 0) {
std::promise<void> p;
auto f = p.get_future();
checktime_thread = std::thread([&p]() {
fc::set_os_thread_name("checktime");
checktime_ios = std::make_unique<boost::asio::io_service>();
@@ -37,7 +36,7 @@ platform_timer::platform_timer() {
checktime_ios->run();
});
f.get();
p.get_future().get();
}
my->timer = std::make_unique<boost::asio::high_resolution_timer>(*checktime_ios);
@@ -65,12 +64,11 @@ void platform_timer::start(fc::time_point tp) {
else {
#if 0
std::promise<void> p;
auto f = p.get_future();
checktime_ios->post([&p,this]() {
expired = 0;
p.set_value();
});
f.get();
p.get_future().get();
#endif
expired = 0;
my->timer->expires_after(std::chrono::microseconds(x.count()));
View File
+2 -202
View File
@@ -4,7 +4,6 @@
#include <eosio/chain/deep_mind.hpp>
#include <fc/scoped_exit.hpp>
#include <fc/io/json.hpp>
#include <algorithm>
#include <boost/assign/list_of.hpp>
@@ -569,7 +568,7 @@ Enables new `get_block_num` intrinsic which returns the current block number.
protocol_feature_manager::protocol_feature_manager(
protocol_feature_set&& pfs,
std::function<deep_mind_handler*(bool is_trx_transient)> get_deep_mind_logger
std::function<deep_mind_handler*()> get_deep_mind_logger
):_protocol_feature_set( std::move(pfs) ), _get_deep_mind_logger(get_deep_mind_logger)
{
_builtin_protocol_features.resize( _protocol_feature_set._recognized_builtin_protocol_features.size() );
@@ -750,8 +749,7 @@ Enables new `get_block_num` intrinsic which returns the current block number.
("digest", feature_digest)
);
// activate_feature is called by init. no transaction specific logging is possible
if (auto dm_logger = _get_deep_mind_logger(false)) {
if (auto dm_logger = _get_deep_mind_logger()) {
dm_logger->on_activate_feature(*itr);
}
@@ -780,202 +778,4 @@ Enables new `get_block_num` intrinsic which returns the current block number.
}
}
std::optional<builtin_protocol_feature> read_builtin_protocol_feature( const fc::path& p ) {
try {
return fc::json::from_file<builtin_protocol_feature>( p );
} catch( const fc::exception& e ) {
wlog( "problem encountered while reading '${path}':\n${details}",
("path", p.generic_string())("details",e.to_detail_string()) );
} catch( ... ) {
dlog( "unknown problem encountered while reading '${path}'",
("path", p.generic_string()) );
}
return {};
}
protocol_feature_set initialize_protocol_features( const fc::path& p, bool populate_missing_builtins ) {
using boost::filesystem::directory_iterator;
protocol_feature_set pfs;
bool directory_exists = true;
if( fc::exists( p ) ) {
EOS_ASSERT( fc::is_directory( p ), plugin_exception,
"Path to protocol-features is not a directory: ${path}",
("path", p.generic_string())
);
} else {
if( populate_missing_builtins )
boost::filesystem::create_directories( p );
else
directory_exists = false;
}
auto log_recognized_protocol_feature = []( const builtin_protocol_feature& f, const digest_type& feature_digest ) {
if( f.subjective_restrictions.enabled ) {
if( f.subjective_restrictions.preactivation_required ) {
if( f.subjective_restrictions.earliest_allowed_activation_time == time_point{} ) {
ilog( "Support for builtin protocol feature '${codename}' (with digest of '${digest}') is enabled with preactivation required",
("codename", builtin_protocol_feature_codename(f.get_codename()))
("digest", feature_digest)
);
} else {
ilog( "Support for builtin protocol feature '${codename}' (with digest of '${digest}') is enabled with preactivation required and with an earliest allowed activation time of ${earliest_time}",
("codename", builtin_protocol_feature_codename(f.get_codename()))
("digest", feature_digest)
("earliest_time", f.subjective_restrictions.earliest_allowed_activation_time)
);
}
} else {
if( f.subjective_restrictions.earliest_allowed_activation_time == time_point{} ) {
ilog( "Support for builtin protocol feature '${codename}' (with digest of '${digest}') is enabled without activation restrictions",
("codename", builtin_protocol_feature_codename(f.get_codename()))
("digest", feature_digest)
);
} else {
ilog( "Support for builtin protocol feature '${codename}' (with digest of '${digest}') is enabled without preactivation required but with an earliest allowed activation time of ${earliest_time}",
("codename", builtin_protocol_feature_codename(f.get_codename()))
("digest", feature_digest)
("earliest_time", f.subjective_restrictions.earliest_allowed_activation_time)
);
}
}
} else {
ilog( "Recognized builtin protocol feature '${codename}' (with digest of '${digest}') but support for it is not enabled",
("codename", builtin_protocol_feature_codename(f.get_codename()))
("digest", feature_digest)
);
}
};
map<builtin_protocol_feature_t, fc::path> found_builtin_protocol_features;
map<digest_type, std::pair<builtin_protocol_feature, bool> > builtin_protocol_features_to_add;
// The bool in the pair is set to true if the builtin protocol feature has already been visited to add
map< builtin_protocol_feature_t, std::optional<digest_type> > visited_builtins;
// Read all builtin protocol features
if( directory_exists ) {
for( directory_iterator enditr, itr{p}; itr != enditr; ++itr ) {
auto file_path = itr->path();
if( !fc::is_regular_file( file_path ) || file_path.extension().generic_string().compare( ".json" ) != 0 )
continue;
auto f = read_builtin_protocol_feature( file_path );
if( !f ) continue;
auto res = found_builtin_protocol_features.emplace( f->get_codename(), file_path );
EOS_ASSERT( res.second, plugin_exception,
"Builtin protocol feature '${codename}' was already included from a previous_file",
("codename", builtin_protocol_feature_codename(f->get_codename()))
("current_file", file_path.generic_string())
("previous_file", res.first->second.generic_string())
);
const auto feature_digest = f->digest();
builtin_protocol_features_to_add.emplace( std::piecewise_construct,
std::forward_as_tuple( feature_digest ),
std::forward_as_tuple( *f, false ) );
}
}
// Add builtin protocol features to the protocol feature manager in the right order (to satisfy dependencies)
using itr_type = map<digest_type, std::pair<builtin_protocol_feature, bool>>::iterator;
std::function<void(const itr_type&)> add_protocol_feature =
[&pfs, &builtin_protocol_features_to_add, &visited_builtins, &log_recognized_protocol_feature, &add_protocol_feature]( const itr_type& itr ) -> void {
if( itr->second.second ) {
return;
} else {
itr->second.second = true;
visited_builtins.emplace( itr->second.first.get_codename(), itr->first );
}
for( const auto& d : itr->second.first.dependencies ) {
auto itr2 = builtin_protocol_features_to_add.find( d );
if( itr2 != builtin_protocol_features_to_add.end() ) {
add_protocol_feature( itr2 );
}
}
pfs.add_feature( itr->second.first );
log_recognized_protocol_feature( itr->second.first, itr->first );
};
for( auto itr = builtin_protocol_features_to_add.begin(); itr != builtin_protocol_features_to_add.end(); ++itr ) {
add_protocol_feature( itr );
}
auto output_protocol_feature = [&p]( const builtin_protocol_feature& f, const digest_type& feature_digest ) {
string filename( "BUILTIN-" );
filename += builtin_protocol_feature_codename( f.get_codename() );
filename += ".json";
auto file_path = p / filename;
EOS_ASSERT( !fc::exists( file_path ), plugin_exception,
"Could not save builtin protocol feature with codename '${codename}' because a file at the following path already exists: ${path}",
("codename", builtin_protocol_feature_codename( f.get_codename() ))
("path", file_path.generic_string())
);
if( fc::json::save_to_file( f, file_path ) ) {
ilog( "Saved default specification for builtin protocol feature '${codename}' (with digest of '${digest}') to: ${path}",
("codename", builtin_protocol_feature_codename(f.get_codename()))
("digest", feature_digest)
("path", file_path.generic_string())
);
} else {
elog( "Error occurred while writing default specification for builtin protocol feature '${codename}' (with digest of '${digest}') to: ${path}",
("codename", builtin_protocol_feature_codename(f.get_codename()))
("digest", feature_digest)
("path", file_path.generic_string())
);
}
};
std::function<digest_type(builtin_protocol_feature_t)> add_missing_builtins =
[&pfs, &visited_builtins, &output_protocol_feature, &log_recognized_protocol_feature, &add_missing_builtins, populate_missing_builtins]
( builtin_protocol_feature_t codename ) -> digest_type {
auto res = visited_builtins.emplace( codename, std::optional<digest_type>() );
if( !res.second ) {
EOS_ASSERT( res.first->second, protocol_feature_exception,
"invariant failure: cycle found in builtin protocol feature dependencies"
);
return *res.first->second;
}
auto f = protocol_feature_set::make_default_builtin_protocol_feature( codename,
[&add_missing_builtins]( builtin_protocol_feature_t d ) {
return add_missing_builtins( d );
} );
if( !populate_missing_builtins )
f.subjective_restrictions.enabled = false;
const auto& pf = pfs.add_feature( f );
res.first->second = pf.feature_digest;
log_recognized_protocol_feature( f, pf.feature_digest );
if( populate_missing_builtins )
output_protocol_feature( f, pf.feature_digest );
return pf.feature_digest;
};
for( const auto& p : builtin_protocol_feature_codenames ) {
auto itr = found_builtin_protocol_features.find( p.first );
if( itr != found_builtin_protocol_features.end() ) continue;
add_missing_builtins( p.first );
}
return pfs;
}
} } // eosio::chain
+20 -49
View File
@@ -65,8 +65,7 @@ void resource_limits_manager::initialize_database() {
state.virtual_net_limit = config.net_limit_parameters.max;
});
// At startup, no transaction specific logging is possible
if (auto dm_logger = _get_deep_mind_logger(false)) {
if (auto dm_logger = _get_deep_mind_logger()) {
dm_logger->on_init_resource_limits(config, state);
}
}
@@ -94,7 +93,7 @@ void resource_limits_manager::read_from_snapshot( const snapshot_reader_ptr& sna
});
}
void resource_limits_manager::initialize_account(const account_name& account, bool is_trx_transient) {
void resource_limits_manager::initialize_account(const account_name& account) {
const auto& limits = _db.create<resource_limits_object>([&]( resource_limits_object& bl ) {
bl.owner = account;
});
@@ -102,7 +101,7 @@ void resource_limits_manager::initialize_account(const account_name& account, bo
const auto& usage = _db.create<resource_usage_object>([&]( resource_usage_object& bu ) {
bu.owner = account;
});
if (auto dm_logger = _get_deep_mind_logger(is_trx_transient)) {
if (auto dm_logger = _get_deep_mind_logger()) {
dm_logger->on_newaccount_resource_limits(limits, usage);
}
}
@@ -117,9 +116,7 @@ void resource_limits_manager::set_block_parameters(const elastic_limit_parameter
c.cpu_limit_parameters = cpu_limit_parameters;
c.net_limit_parameters = net_limit_parameters;
// set_block_parameters is called by controller::finalize_block,
// where transaction specific logging is not possible
if (auto dm_logger = _get_deep_mind_logger(false)) {
if (auto dm_logger = _get_deep_mind_logger()) {
dm_logger->on_update_resource_limits_config(c);
}
});
@@ -136,7 +133,7 @@ void resource_limits_manager::update_account_usage(const flat_set<account_name>&
}
}
void resource_limits_manager::add_transaction_usage(const flat_set<account_name>& accounts, uint64_t cpu_usage, uint64_t net_usage, uint32_t time_slot, bool is_trx_transient ) {
void resource_limits_manager::add_transaction_usage(const flat_set<account_name>& accounts, uint64_t cpu_usage, uint64_t net_usage, uint32_t time_slot ) {
const auto& state = _db.get<resource_limits_state_object>();
const auto& config = _db.get<resource_limits_config_object>();
@@ -152,7 +149,7 @@ void resource_limits_manager::add_transaction_usage(const flat_set<account_name>
bu.net_usage.add( net_usage, time_slot, config.account_net_usage_average_window );
bu.cpu_usage.add( cpu_usage, time_slot, config.account_cpu_usage_average_window );
if (auto dm_logger = _get_deep_mind_logger(is_trx_transient)) {
if (auto dm_logger = _get_deep_mind_logger()) {
dm_logger->on_update_account_usage(bu);
}
});
@@ -169,9 +166,8 @@ void resource_limits_manager::add_transaction_usage(const flat_set<account_name>
EOS_ASSERT( cpu_used_in_window <= max_user_use_in_window,
tx_cpu_usage_exceeded,
"authorizing account '${n}' has insufficient objective cpu resources for this transaction,"
" used in window ${cpu_used_in_window}us, allowed in window ${max_user_use_in_window}us",
("n", a)
"authorizing account '${n}' has insufficient cpu resources for this transaction",
("n", name(a))
("cpu_used_in_window",cpu_used_in_window)
("max_user_use_in_window",max_user_use_in_window) );
}
@@ -189,9 +185,8 @@ void resource_limits_manager::add_transaction_usage(const flat_set<account_name>
EOS_ASSERT( net_used_in_window <= max_user_use_in_window,
tx_net_usage_exceeded,
"authorizing account '${n}' has insufficient net resources for this transaction,"
" used in window ${net_used_in_window}, allowed in window ${max_user_use_in_window}",
("n", a)
"authorizing account '${n}' has insufficient net resources for this transaction",
("n", name(a))
("net_used_in_window",net_used_in_window)
("max_user_use_in_window",max_user_use_in_window) );
@@ -208,7 +203,7 @@ void resource_limits_manager::add_transaction_usage(const flat_set<account_name>
EOS_ASSERT( state.pending_net_usage <= config.net_limit_parameters.max, block_resource_exhausted, "Block has insufficient net resources" );
}
void resource_limits_manager::add_pending_ram_usage( const account_name account, int64_t ram_delta, bool is_trx_transient ) {
void resource_limits_manager::add_pending_ram_usage( const account_name account, int64_t ram_delta ) {
if (ram_delta == 0) {
return;
}
@@ -223,7 +218,7 @@ void resource_limits_manager::add_pending_ram_usage( const account_name account,
_db.modify( usage, [&]( auto& u ) {
u.ram_usage += ram_delta;
if (auto dm_logger = _get_deep_mind_logger(is_trx_transient)) {
if (auto dm_logger = _get_deep_mind_logger()) {
dm_logger->on_ram_event(account, u.ram_usage, ram_delta);
}
});
@@ -246,7 +241,7 @@ int64_t resource_limits_manager::get_account_ram_usage( const account_name& name
}
bool resource_limits_manager::set_account_limits( const account_name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight, bool is_trx_transient) {
bool resource_limits_manager::set_account_limits( const account_name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight) {
//const auto& usage = _db.get<resource_usage_object,by_owner>( account );
/*
* Since we need to delay these until the next resource limiting boundary, these are created in a "pending"
@@ -292,7 +287,7 @@ bool resource_limits_manager::set_account_limits( const account_name& account, i
pending_limits.net_weight = net_weight;
pending_limits.cpu_weight = cpu_weight;
if (auto dm_logger = _get_deep_mind_logger(is_trx_transient)) {
if (auto dm_logger = _get_deep_mind_logger()) {
dm_logger->on_set_account_limits(pending_limits);
}
});
@@ -359,9 +354,7 @@ void resource_limits_manager::process_account_limit_updates() {
multi_index.remove(*itr);
}
// process_account_limit_updates is called by controller::finalize_block,
// where transaction specific logging is not possible
if (auto dm_logger = _get_deep_mind_logger(false)) {
if (auto dm_logger = _get_deep_mind_logger()) {
dm_logger->on_update_resource_limits_state(state);
}
});
@@ -381,9 +374,7 @@ void resource_limits_manager::process_block_usage(uint32_t block_num) {
state.update_virtual_net_limit(config);
state.pending_net_usage = 0;
// process_block_usage is called by controller::finalize_block,
// where transaction specific logging is not possible
if (auto dm_logger = _get_deep_mind_logger(false)) {
if (auto dm_logger = _get_deep_mind_logger()) {
dm_logger->on_update_resource_limits_state(state);
}
});
@@ -427,8 +418,7 @@ std::pair<int64_t, bool> resource_limits_manager::get_account_cpu_limit( const a
return {arl.available, greylisted};
}
std::pair<account_resource_limit, bool>
resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, uint32_t greylist_limit, const std::optional<block_timestamp_type>& current_time) const {
std::pair<account_resource_limit, bool> resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, uint32_t greylist_limit ) const {
const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name);
@@ -438,7 +428,7 @@ resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, uin
get_account_limits( name, x, y, cpu_weight );
if( cpu_weight < 0 || state.total_cpu_weight == 0 ) {
return {{ -1, -1, -1, block_timestamp_type(usage.cpu_usage.last_ordinal), -1 }, false};
return {{ -1, -1, -1 }, false};
}
account_resource_limit arl;
@@ -472,15 +462,6 @@ resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, uin
arl.used = impl::downgrade_cast<int64_t>(cpu_used_in_window);
arl.max = impl::downgrade_cast<int64_t>(max_user_use_in_window);
arl.last_usage_update_time = block_timestamp_type(usage.cpu_usage.last_ordinal);
arl.current_used = arl.used;
if ( current_time ) {
if (current_time->slot > usage.cpu_usage.last_ordinal) {
auto history_usage = usage.cpu_usage;
history_usage.add(0, current_time->slot, window_size);
arl.current_used = impl::downgrade_cast<int64_t>(impl::integer_divide_ceil((uint128_t)history_usage.value_ex * window_size, (uint128_t)config::rate_limiting_precision));
}
}
return {arl, greylisted};
}
@@ -489,8 +470,7 @@ std::pair<int64_t, bool> resource_limits_manager::get_account_net_limit( const a
return {arl.available, greylisted};
}
std::pair<account_resource_limit, bool>
resource_limits_manager::get_account_net_limit_ex( const account_name& name, uint32_t greylist_limit, const std::optional<block_timestamp_type>& current_time) const {
std::pair<account_resource_limit, bool> resource_limits_manager::get_account_net_limit_ex( const account_name& name, uint32_t greylist_limit ) const {
const auto& config = _db.get<resource_limits_config_object>();
const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name);
@@ -499,7 +479,7 @@ resource_limits_manager::get_account_net_limit_ex( const account_name& name, uin
get_account_limits( name, x, net_weight, y );
if( net_weight < 0 || state.total_net_weight == 0) {
return {{ -1, -1, -1, block_timestamp_type(usage.net_usage.last_ordinal), -1 }, false};
return {{ -1, -1, -1 }, false};
}
account_resource_limit arl;
@@ -533,15 +513,6 @@ resource_limits_manager::get_account_net_limit_ex( const account_name& name, uin
arl.used = impl::downgrade_cast<int64_t>(net_used_in_window);
arl.max = impl::downgrade_cast<int64_t>(max_user_use_in_window);
arl.last_usage_update_time = block_timestamp_type(usage.net_usage.last_ordinal);
arl.current_used = arl.used;
if ( current_time ) {
if (current_time->slot > usage.net_usage.last_ordinal) {
auto history_usage = usage.net_usage;
history_usage.add(0, current_time->slot, window_size);
arl.current_used = impl::downgrade_cast<int64_t>(impl::integer_divide_ceil((uint128_t)history_usage.value_ex * window_size, (uint128_t)config::rate_limiting_precision));
}
}
return {arl, greylisted};
}
+49 -134
View File
@@ -1,16 +1,6 @@
#define RAPIDJSON_NAMESPACE eosio_rapidjson // This is ABSOLUTELY necessary anywhere that is using eosio_rapidjson
#include <eosio/chain/snapshot.hpp>
#include <eosio/chain/exceptions.hpp>
#include <fc/scoped_exit.hpp>
#include <fc/io/json.hpp>
#include <rapidjson/document.h>
#include <rapidjson/filereadstream.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
using namespace eosio_rapidjson;
namespace eosio { namespace chain {
@@ -86,6 +76,17 @@ void variant_snapshot_reader::validate() const {
}
}
bool variant_snapshot_reader::has_section( const string& section_name ) {
const auto& sections = snapshot["sections"].get_array();
for( const auto& section: sections ) {
if (section["name"].as_string() == section_name) {
return true;
}
}
return false;
}
void variant_snapshot_reader::set_section( const string& section_name ) {
const auto& sections = snapshot["sections"].get_array();
for( const auto& section: sections ) {
@@ -189,45 +190,6 @@ void ostream_snapshot_writer::finalize() {
snapshot.write((char*)&end_marker, sizeof(end_marker));
}
ostream_json_snapshot_writer::ostream_json_snapshot_writer(std::ostream& snapshot)
:snapshot(snapshot)
,row_count(0)
{
snapshot << "{\n";
// write magic number
auto totem = magic_number;
snapshot << "\"magic_number\":" << fc::json::to_string(totem, fc::time_point::maximum()) << "\n";
// write version
auto version = current_snapshot_version;
snapshot << ",\"version\":" << fc::json::to_string(version, fc::time_point::maximum()) << "\n";
}
void ostream_json_snapshot_writer::write_start_section( const std::string& section_name )
{
row_count = 0;
snapshot.inner << "," << fc::json::to_string(section_name, fc::time_point::maximum()) << ":{\n\"rows\":[\n";
}
void ostream_json_snapshot_writer::write_row( const detail::abstract_snapshot_row_writer& row_writer ) {
const auto yield = [&](size_t s) {};
if(row_count != 0) snapshot.inner << ",";
snapshot.inner << fc::json::to_string(row_writer.to_variant(), yield) << "\n";
++row_count;
}
void ostream_json_snapshot_writer::write_end_section( ) {
snapshot.inner << "],\n\"num_rows\":" << row_count << "\n}\n";
row_count = 0;
}
void ostream_json_snapshot_writer::finalize() {
snapshot.inner << "}\n";
snapshot.inner.flush();
}
istream_snapshot_reader::istream_snapshot_reader(std::istream& snapshot)
:snapshot(snapshot)
,header_pos(snapshot.tellg())
@@ -284,6 +246,44 @@ bool istream_snapshot_reader::validate_section() const {
return true;
}
bool istream_snapshot_reader::has_section( const string& section_name ) {
auto restore_pos = fc::make_scoped_exit([this,pos=snapshot.tellg()](){
snapshot.seekg(pos);
});
const std::streamoff header_size = sizeof(ostream_snapshot_writer::magic_number) + sizeof(current_snapshot_version);
auto next_section_pos = header_pos + header_size;
while (true) {
snapshot.seekg(next_section_pos);
uint64_t section_size = 0;
snapshot.read((char*)&section_size,sizeof(section_size));
if (section_size == std::numeric_limits<uint64_t>::max()) {
break;
}
next_section_pos = snapshot.tellg() + std::streamoff(section_size);
uint64_t ignore = 0;
snapshot.read((char*)&ignore,sizeof(ignore));
bool match = true;
for(auto c : section_name) {
if(snapshot.get() != c) {
match = false;
break;
}
}
if (match && snapshot.get() == 0) {
return true;
}
}
return false;
}
void istream_snapshot_reader::set_section( const string& section_name ) {
auto restore_pos = fc::make_scoped_exit([this,pos=snapshot.tellg()](){
snapshot.seekg(pos);
@@ -346,91 +346,6 @@ void istream_snapshot_reader::return_to_header() {
clear_section();
}
struct istream_json_snapshot_reader_impl {
uint64_t num_rows;
uint64_t cur_row;
eosio_rapidjson::Document doc;
std::string sec_name;
};
istream_json_snapshot_reader::~istream_json_snapshot_reader() = default;
istream_json_snapshot_reader::istream_json_snapshot_reader(const fc::path& p)
: impl{new istream_json_snapshot_reader_impl{0, 0, {}, {}}}
{
FILE* fp = fopen(p.string().c_str(), "rb");
EOS_ASSERT(fp, snapshot_exception, "Failed to open JSON snapshot: ${file}", ("file", p));
auto close = fc::make_scoped_exit( [&fp]() { fclose( fp ); } );
char readBuffer[65536];
eosio_rapidjson::FileReadStream is(fp, readBuffer, sizeof(readBuffer));
impl->doc.ParseStream(is);
}
void istream_json_snapshot_reader::validate() const {
try {
// validate totem
auto expected_totem = ostream_json_snapshot_writer::magic_number;
EOS_ASSERT(impl->doc.HasMember("magic_number"), snapshot_exception, "magic_number section not found" );
auto actual_totem = impl->doc["magic_number"].GetUint();
EOS_ASSERT( actual_totem == expected_totem, snapshot_exception, "JSON snapshot has unexpected magic number" );
// validate version
auto expected_version = current_snapshot_version;
EOS_ASSERT(impl->doc.HasMember("version"), snapshot_exception, "version section not found" );
auto actual_version = impl->doc["version"].GetUint();
EOS_ASSERT( actual_version == expected_version, snapshot_exception,
"JSON snapshot is an unsupported version. Expected : ${expected}, Got: ${actual}",
("expected", expected_version)( "actual", actual_version ) );
} catch( const std::exception& e ) { \
snapshot_exception fce(FC_LOG_MESSAGE( warn, "JSON snapshot validation threw IO exception (${what})",("what",e.what())));
throw fce;
}
}
bool istream_json_snapshot_reader::validate_section() const {
return true;
}
void istream_json_snapshot_reader::set_section( const string& section_name ) {
EOS_ASSERT( impl->doc.HasMember( section_name.c_str() ), snapshot_exception, "JSON snapshot has no section ${sec}", ("sec", section_name) );
EOS_ASSERT( impl->doc[section_name.c_str()].HasMember( "num_rows" ), snapshot_exception, "JSON snapshot ${sec} num_rows not found", ("sec", section_name) );
EOS_ASSERT( impl->doc[section_name.c_str()].HasMember( "rows" ), snapshot_exception, "JSON snapshot ${sec} rows not found", ("sec", section_name) );
EOS_ASSERT( impl->doc[section_name.c_str()]["rows"].IsArray(), snapshot_exception, "JSON snapshot ${sec} rows is not an array", ("sec_name", section_name) );
impl->sec_name = section_name;
impl->num_rows = impl->doc[section_name.c_str()]["num_rows"].GetInt();
ilog( "reading ${section_name}, num_rows: ${num_rows}", ("section_name", section_name)( "num_rows", impl->num_rows ) );
}
bool istream_json_snapshot_reader::read_row( detail::abstract_snapshot_row_reader& row_reader ) {
EOS_ASSERT( impl->cur_row < impl->num_rows, snapshot_exception, "JSON snapshot ${sect}'s cur_row ${cur_row} >= num_rows ${num_rows}",
("sect_name", impl->sec_name)( "cur_row", impl->cur_row )( "num_rows", impl->num_rows ) );
const eosio_rapidjson::Value& rows = impl->doc[impl->sec_name.c_str()]["rows"];
eosio_rapidjson::StringBuffer buffer;
eosio_rapidjson::Writer<eosio_rapidjson::StringBuffer> writer( buffer );
rows[impl->cur_row].Accept( writer );
const auto& row = fc::json::from_string( buffer.GetString() );
row_reader.provide( row );
return ++impl->cur_row < impl->num_rows;
}
bool istream_json_snapshot_reader::empty ( ) {
return impl->num_rows == 0;
}
void istream_json_snapshot_reader::clear_section() {
impl->num_rows = 0;
impl->cur_row = 0;
impl->sec_name = "";
}
void istream_json_snapshot_reader::return_to_header() {
clear_section();
}
integrity_hash_snapshot_writer::integrity_hash_snapshot_writer(fc::sha256::encoder& enc)
:enc(enc)
{
+36
View File
@@ -0,0 +1,36 @@
#include <eosio/chain/thread_utils.hpp>
#include <fc/log/logger_config.hpp>
namespace eosio { namespace chain {
//
// named_thread_pool
//
named_thread_pool::named_thread_pool( std::string name_prefix, size_t num_threads )
: _thread_pool( num_threads )
, _ioc( num_threads )
{
_ioc_work.emplace( boost::asio::make_work_guard( _ioc ) );
for( size_t i = 0; i < num_threads; ++i ) {
boost::asio::post( _thread_pool, [&ioc = _ioc, name_prefix, i]() {
std::string tn = name_prefix + "-" + std::to_string( i );
fc::set_os_thread_name( tn );
ioc.run();
} );
}
}
named_thread_pool::~named_thread_pool() {
stop();
}
void named_thread_pool::stop() {
_ioc_work.reset();
_ioc.stop();
_thread_pool.join();
_thread_pool.stop();
}
} } // eosio::chain

Some files were not shown because too many files have changed in this diff Show More