зеркало из https://github.com/microsoft/CCF.git
Add documentation and test for new oeverify tool (#1761)
This commit is contained in:
Родитель
3a98f44784
Коммит
70d8c85648
81
CHANGELOG.md
81
CHANGELOG.md
|
@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Changed
|
||||
- `node/quote` endpoint now returns a single JSON object containing the node's quote (#1761).
|
||||
|
||||
## [0.14.1]
|
||||
### Added
|
||||
- `/node/memory` endpoint exposing the maximum configured heap size, peak and current used sizes.
|
||||
|
@ -43,7 +46,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
### Changed
|
||||
- Fixed infinite memory growth issue (#1639)
|
||||
- Step CLI updated to 0.15.2 (#1636)
|
||||
|
||||
|
||||
## [0.13.3]
|
||||
### Added
|
||||
- Sample TypeScript application (#1614, #1596)
|
||||
|
@ -60,17 +63,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
|
||||
### Removed
|
||||
- Notification server (#1582)
|
||||
|
||||
|
||||
## [0.13.2]
|
||||
### Added
|
||||
- retire_node_code proposal (#1558)
|
||||
- Ability to update a collection of JS modules in a single proposal (#1557)
|
||||
|
||||
|
||||
## [0.13.1]
|
||||
### Fixed
|
||||
- Handle setting multiple subject alternative names correctly in node certificate (#1552)
|
||||
- Fix host memory check on startup ecall (#1553)
|
||||
|
||||
|
||||
## [0.13.0]
|
||||
### Added
|
||||
- Experimental
|
||||
|
@ -92,24 +95,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
|
||||
### Deprecated
|
||||
- CLI
|
||||
- `--domain=...` is superseded by `--san=dNSName:...` and will be removed in a future release
|
||||
- `--domain=...` is superseded by `--san=dNSName:...` and will be removed in a future release
|
||||
|
||||
### Removed
|
||||
- API
|
||||
- Removed redirection from legacy frontend names (`members` -> `gov`, `nodes` -> `node`, `users` -> `app`) (#1543)
|
||||
- Removed old `install()` API, replaced by `make_endpoint()` in [0.11.1](https://github.com/microsoft/CCF/releases/tag/ccf-0.11.1) (#1541)
|
||||
|
||||
|
||||
## [0.12.2]
|
||||
### Fixed
|
||||
- Fix published containers
|
||||
|
||||
|
||||
## [0.12.1]
|
||||
### Changed
|
||||
- Release tarball replaced by a .deb
|
||||
|
||||
### Fixed
|
||||
- Fix LVI build for applications using CCF (#1466)
|
||||
|
||||
|
||||
## [0.12.0]
|
||||
### Added
|
||||
- Tooling
|
||||
|
@ -140,7 +143,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
|
||||
### Removed
|
||||
- `mkSign` endpoint (#1398).
|
||||
|
||||
|
||||
## [0.11.7]
|
||||
### Changed
|
||||
1. Fix a bug that could cause signatures not to be recorded on transactions hitting conflicts (#1346)
|
||||
|
@ -150,7 +153,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
### Added
|
||||
1. All format and linting checks are now covered by `scripts/ci-checks.sh` (#1359)
|
||||
2. `node/code` RPC returns all code versions and their status (#1351)
|
||||
|
||||
|
||||
## [0.11.4]
|
||||
### Changed
|
||||
- Add clang-format to the application CI container, to facilitate application development (#1340)
|
||||
|
@ -159,7 +162,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
|
||||
### Fixed
|
||||
- Fix application runtime container, which had been missing a dependency in the previous release (#1340)
|
||||
|
||||
|
||||
## [0.11.1]
|
||||
### Added
|
||||
- CLI tool for managing recovery shares (#1295). [usage](https://microsoft.github.io/CCF/master/members/accept_recovery.html#submitting-recovery-shares)
|
||||
|
@ -173,7 +176,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- Improved quickstart documentation (#1298, #1316).
|
||||
- Member ACKs are required, even when the service is opening (#1318).
|
||||
- The naming scheme for releases has changed to be more consistent. The tags will now be in the form `ccf-X.Y.Z`.
|
||||
|
||||
|
||||
## [0.11]
|
||||
### Changed
|
||||
- KV reorganisation to enable app-defined serialisation (#1179, #1216, #1234)
|
||||
|
@ -202,7 +205,7 @@ CCF now deals internally only with serialised data in its tables, mapping byte-v
|
|||
|
||||
### Removed
|
||||
- `ccf::Store` and `ccf::Tx` typdefs, in favour of `kv::Store` and `kv::Tx`.
|
||||
|
||||
|
||||
## [0.10]
|
||||
### Added
|
||||
- Brand new versioned documentation: https://microsoft.github.io/CCF.
|
||||
|
@ -221,17 +224,17 @@ CCF now deals internally only with serialised data in its tables, mapping byte-v
|
|||
- Updated method to retrieve time in enclave from host (#1100).
|
||||
- Correct use of Everycrypt hashing (#1098).
|
||||
- Maximum number of active members is 255 (#1107).
|
||||
- Python infra: handle proposals correctly with single member (#1079).
|
||||
- Python infra: handle proposals correctly with single member (#1079).
|
||||
- Dependencies updates (#1080, #1082).
|
||||
|
||||
### Removed
|
||||
- `cchost` no longer outputs a sealed secrets file to be used for recovery (#1101).
|
||||
|
||||
|
||||
## [0.9.3]
|
||||
### Added
|
||||
1. Install artifacts include `virtual` build (#1072)
|
||||
2. `add_enclave_library_c` is exposed in `ccp_app.cmake` (#1073)
|
||||
|
||||
|
||||
## [0.9.2]
|
||||
### Added
|
||||
- Handlers can decide if transaction writes are applied independently from error status (#1054)
|
||||
|
@ -241,11 +244,11 @@ CCF now deals internally only with serialised data in its tables, mapping byte-v
|
|||
- Handle writes when host is reconnecting (#1038)
|
||||
- Member tables are no longer whitelisted for raw_puts (#1041)
|
||||
- Projects including CCF's CMake files now use the same build type default (#1057)
|
||||
|
||||
|
||||
## [0.9.1]
|
||||
### Added
|
||||
- `cchost` now supports [file-based configuration](https://microsoft.github.io/CCF/operators/start_network.html#using-a-configuration-file), as well as command-line switches (#1013, #1019)
|
||||
|
||||
|
||||
## [0.9]
|
||||
|
||||
This pre-release improves support for handling HTTP requests.
|
||||
|
@ -267,13 +270,13 @@ This pre-release improves support for handling HTTP requests.
|
|||
- Consensus is chosen at run-time, rather than build-time (#922).
|
||||
- API for installing handlers has changed (#960). See the logging app or [documentation](https://microsoft.github.io/CCF/developers/logging_cpp.html#rpc-handler) for the current style.
|
||||
- Several standard endpoints are now GET-only, and must be passed a URL query (ie `GET /users/getCommit?id=42`).
|
||||
|
||||
|
||||
## [0.8.2]
|
||||
### Changed
|
||||
- CCF install can now be installed anywhere (#950).
|
||||
- PBFT messages are now authenticated (#947).
|
||||
- Miscellaneous performance improvements (#946).
|
||||
|
||||
|
||||
## [0.8.1]
|
||||
### Added
|
||||
- PBFT timers can be set from`cchost` CLI (#929). See [docs](https://microsoft.github.io/CCF/developers/consensus.html#consensus-protocols).
|
||||
|
@ -287,7 +290,7 @@ This pre-release improves support for handling HTTP requests.
|
|||
- Original consortium members can ACK (#933).
|
||||
- PBFT performance improvements (#940, #942).
|
||||
- PBFT ledger private tables are now encrypted (#939).
|
||||
|
||||
|
||||
## [0.8]
|
||||
|
||||
This pre-release enables experimental support for running CCF with the PBFT consensus protocol. In providing an experimental release of CCF with PBFT we hope to get feedback from early adopters.
|
||||
|
@ -310,12 +313,12 @@ This pre-release enables experimental support for running CCF with the PBFT cons
|
|||
|
||||
### Removed
|
||||
- FramedTCP support
|
||||
|
||||
|
||||
## [0.7.1]
|
||||
### Added
|
||||
- Installed Python infrastructure can now be used to launch test networks of external builds (#809)
|
||||
- Initial threading support, Raft nodes now execute transactions on multiple worker threads (#773, #822)
|
||||
|
||||
|
||||
## [0.7]
|
||||
|
||||
This pre-release enables experimental support for Javascript as a CCF runtime, and switches the default transport to HTTP. FramedTCP is still supported in this release (`-DFTCP=ON`) but is deprecated and will be dropped in the next release.
|
||||
|
@ -332,7 +335,7 @@ This pre-release enables experimental support for Javascript as a CCF runtime, a
|
|||
|
||||
### Deprecated
|
||||
- FramedTCP support. Please use the ccf_FTCP.tar.gz release bundle or build CCF with `-DFTCP=ON` if you require FTCP support.
|
||||
|
||||
|
||||
## [0.6]
|
||||
|
||||
This pre-release enables support for HTTP in CCF
|
||||
|
@ -341,43 +344,43 @@ This pre-release enables support for HTTP in CCF
|
|||
- Quote format in `getQuotes` changed from string to vector of bytes (https://github.com/microsoft/CCF/pull/566)
|
||||
- Improved error reporting and logging (https://github.com/microsoft/CCF/pull/572, https://github.com/microsoft/CCF/pull/577, https://github.com/microsoft/CCF/pull/620)
|
||||
- Node certificates endorsed by the network (https://github.com/microsoft/CCF/pull/581)
|
||||
- The [`keygenerator.sh`](https://github.com/microsoft/CCF/blob/v0.6/tests/keygenerator.sh) scripts replaces the `keygenerator` CLI utility to generate member and user identities.
|
||||
- The [`keygenerator.sh`](https://github.com/microsoft/CCF/blob/v0.6/tests/keygenerator.sh) scripts replaces the `keygenerator` CLI utility to generate member and user identities.
|
||||
|
||||
### Added
|
||||
- HTTP endpoint support when built with `-DHTTP=ON`, see https://microsoft.github.io/CCF/users/client.html for details.
|
||||
- [Only when building with `-DHTTP=ON`] The new [`scurl.sh`](https://github.com/microsoft/CCF/blob/v0.6/tests/scurl.sh) script can be used to issue signed HTTP requests to CCF (e.g. for member votes). The script takes the same arguments as `curl`.
|
||||
- [Only when building with `-DHTTP=ON`] The new [`scurl.sh`](https://github.com/microsoft/CCF/blob/v0.6/tests/scurl.sh) script can be used to issue signed HTTP requests to CCF (e.g. for member votes). The script takes the same arguments as `curl`.
|
||||
- `listMethods` RPC for luageneric app (https://github.com/microsoft/CCF/pull/570)
|
||||
- `getReceipt`/`verifyReceipt` RPCs (https://github.com/microsoft/CCF/pull/567)
|
||||
- Support for app-defined ACLs (https://github.com/microsoft/CCF/pull/590)
|
||||
|
||||
Binaries for `cchost` and `libluagenericenc.so` are attached to this release. Note that libluagenericenc.so should be signed before being deployed by CCF (see https://microsoft.github.io/CCF/developers/build_app.html#standalone-signing).
|
||||
|
||||
|
||||
## [0.5]
|
||||
|
||||
This pre-release fixes minor issues and clarifies some of `cchost` command line options.
|
||||
This pre-release fixes minor issues and clarifies some of `cchost` command line options.
|
||||
|
||||
### Removed
|
||||
- The `new_user` function in constitution scripts (e.g. `gov.lua`) should be deleted as it is now directly implemented inside CCF (https://github.com/microsoft/CCF/pull/550).
|
||||
- `cmake -DTARGET=all` replaced with `cmake -DTARGET=sgx;virtual`. See https://microsoft.github.io/CCF/quickstart/build.html#build-switches for new values (https://github.com/microsoft/CCF/pull/513).
|
||||
- The `new_user` function in constitution scripts (e.g. `gov.lua`) should be deleted as it is now directly implemented inside CCF (https://github.com/microsoft/CCF/pull/550).
|
||||
- `cmake -DTARGET=all` replaced with `cmake -DTARGET=sgx;virtual`. See https://microsoft.github.io/CCF/quickstart/build.html#build-switches for new values (https://github.com/microsoft/CCF/pull/513).
|
||||
|
||||
### Changed
|
||||
- The members and users certificates can now be registered by the consortium using clients that are not the `memberclient` CLI (e.g. using the `tests/infra/jsonrpc.py` module) (https://github.com/microsoft/CCF/pull/550).
|
||||
- Fix for Raft consensus to truncate the ledger whenever a rollback occurs and use `commit_idx` instead of `last_idx` in many places because of signatures (https://github.com/microsoft/CCF/pull/503).
|
||||
- Join protocol over HTTP fix (https://github.com/microsoft/CCF/pull/550).
|
||||
- Clearer error messages for when untrusted users/members issue transactions to CCF (https://github.com/microsoft/CCF/pull/530).
|
||||
- The members and users certificates can now be registered by the consortium using clients that are not the `memberclient` CLI (e.g. using the `tests/infra/jsonrpc.py` module) (https://github.com/microsoft/CCF/pull/550).
|
||||
- Fix for Raft consensus to truncate the ledger whenever a rollback occurs and use `commit_idx` instead of `last_idx` in many places because of signatures (https://github.com/microsoft/CCF/pull/503).
|
||||
- Join protocol over HTTP fix (https://github.com/microsoft/CCF/pull/550).
|
||||
- Clearer error messages for when untrusted users/members issue transactions to CCF (https://github.com/microsoft/CCF/pull/530).
|
||||
- `devcontainer.json` now points to right Dockerfile (https://github.com/microsoft/CCF/pull/543).
|
||||
- `cchost --raft-election-timeout` CLI option default now set to 5000 ms (https://github.com/microsoft/CCF/pull/559).
|
||||
- Better descriptions for `cchost` command line options (e.g. `--raft-election-timeout`) (https://github.com/microsoft/CCF/pull/559).
|
||||
- Better descriptions for `cchost` command line options (e.g. `--raft-election-timeout`) (https://github.com/microsoft/CCF/pull/559).
|
||||
|
||||
The `cchost`, `libluagenericenc.so`, `keygenerator` and `memberclient` are also attached to this release to start a CCF network with lua application.
|
||||
Note that `libluagenericenc.so` should be signed before being deployed by CCF (see https://microsoft.github.io/CCF/developers/build_app.html#standalone-signing).
|
||||
|
||||
The `cchost`, `libluagenericenc.so`, `keygenerator` and `memberclient` are also attached to this release to start a CCF network with lua application.
|
||||
Note that `libluagenericenc.so` should be signed before being deployed by CCF (see https://microsoft.github.io/CCF/developers/build_app.html#standalone-signing).
|
||||
|
||||
## [0.4]
|
||||
|
||||
In this preview release, it is possible to run CCF with the PBFT consensus algorithm, albeit with significant limitations.
|
||||
|
||||
The evercrypt submodule has been removed, the code is instead imported, to make release tarballs easier to use.
|
||||
|
||||
|
||||
## [0.3]
|
||||
|
||||
This pre-release implements the genesis model described in the TR, with a distinct service opening phase. See https://microsoft.github.io/CCF/start_network.html for details.
|
||||
|
|
|
@ -239,8 +239,6 @@ create_patched_enclave_lib(
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/apps/sample_key.pem
|
||||
)
|
||||
|
||||
set(OE_SIGN_PATH ${OE_BINDIR}/oesign)
|
||||
|
||||
if(BUILD_TESTS)
|
||||
enable_testing()
|
||||
|
||||
|
@ -622,6 +620,8 @@ if(BUILD_TESTS)
|
|||
CONSENSUS cft
|
||||
LABEL suite
|
||||
ADDITIONAL_ARGS
|
||||
--oe-binary
|
||||
${OE_BINDIR}
|
||||
--ledger-recovery-timeout
|
||||
20
|
||||
--test-duration
|
||||
|
@ -692,14 +692,14 @@ if(BUILD_TESTS)
|
|||
NAME code_update_test
|
||||
PYTHON_SCRIPT ${CMAKE_SOURCE_DIR}/tests/code_update.py
|
||||
CONSENSUS cft
|
||||
ADDITIONAL_ARGS --oesign ${OE_SIGN_PATH} --raft-election-timeout 20000
|
||||
ADDITIONAL_ARGS --oe-binary ${OE_BINDIR} --raft-election-timeout 20000
|
||||
)
|
||||
|
||||
add_e2e_test(
|
||||
NAME governance_test
|
||||
PYTHON_SCRIPT ${CMAKE_SOURCE_DIR}/tests/governance.py
|
||||
CONSENSUS cft
|
||||
ADDITIONAL_ARGS --oesign ${OE_SIGN_PATH} --initial-operator-count 1
|
||||
ADDITIONAL_ARGS --oe-binary ${OE_BINDIR} --initial-operator-count 1
|
||||
)
|
||||
|
||||
add_e2e_test(
|
||||
|
|
|
@ -10,17 +10,22 @@ First, the client should connect to the node to verify, specifying the ``/node/q
|
|||
$ curl https://<ccf-node-address>/node/quote --cacert networkcert.pem
|
||||
{"quotes": [{"mrenclave":"<measurement_hash>, "node_id":<node_id>, "raw":"<hex_encoded_raw_quote>"}]}
|
||||
|
||||
The raw quote should be decoded and output to file for verification via the Open Enclave ``host_verify`` command-line utility:
|
||||
The raw quote should be decoded and output to file for verification via the Open Enclave ``oeverify`` command-line utility:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ curl https://<ccf-node-address>/node/quote --cacert networkcert.pem | jq .quotes[0].raw | xxd -r -p > ccf_node_quote.bin
|
||||
$ curl https://<ccf-node-address>/node/quote --cacert networkcert.pem | jq .raw | xxd -r -p > ccf_node_quote.bin
|
||||
|
||||
$ /opt/openenclave/bin/host_verify -r ccf_node_quote.bin
|
||||
Verifying report ccf_node_quote.bin...
|
||||
Report verification succeeded (0).
|
||||
$ /opt/openenclave/bin/oeverify -r ccf_node_quote.bin -f LEGACY_REPORT_REMOTE
|
||||
Verifying evidence ccf_node_quote.bin...
|
||||
Claims:
|
||||
Enclave unique_id: <ccf_node_mrenclave>
|
||||
Enclave signer_id: <ccf_node_mrsigner>
|
||||
Enclave product_id: <ccf_node_product_id>
|
||||
Enclave sgx_report_data: <ccf_node_report_data>
|
||||
Evidence verification succeeded (0)
|
||||
|
||||
.. note:: The ``host_verify`` CLI is included in the Open Enclave ``hostverify`` package available on the `Open Enclave release page <https://github.com/openenclave/openenclave/releases>`_.
|
||||
.. note:: The ``oeverify`` CLI is included in the Open Enclave ``hostverify`` package available on the `Open Enclave release page <https://github.com/openenclave/openenclave/releases>`_.
|
||||
|
||||
The SGX quotes of all currently trusted nodes can also be retrieved via the ``/node/quotes`` endpoint:
|
||||
|
||||
|
|
|
@ -295,9 +295,9 @@ namespace ccf
|
|||
filter.insert(this->node.get_node_id());
|
||||
this->node.node_quotes(args.tx, result, filter);
|
||||
|
||||
if (result.quotes.size() > 0)
|
||||
if (result.quotes.size() == 1)
|
||||
{
|
||||
return make_success(result);
|
||||
return make_success(result.quotes[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -4,25 +4,189 @@ import infra.e2e_args
|
|||
import infra.network
|
||||
import infra.path
|
||||
import infra.proc
|
||||
import suite.test_requirements as reqs
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from loguru import logger as LOG
|
||||
|
||||
|
||||
def get_code_id(lib_path):
|
||||
oed = subprocess.run(
|
||||
[args.oesign, "dump", "-e", lib_path], capture_output=True, check=True
|
||||
def get_code_id(oe_binary_path, lib_path):
|
||||
res = subprocess.run(
|
||||
[os.path.join(oe_binary_path, "oesign"), "dump", "-e", lib_path],
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
lines = [
|
||||
line
|
||||
for line in oed.stdout.decode().split(os.linesep)
|
||||
for line in res.stdout.decode().split(os.linesep)
|
||||
if line.startswith("mrenclave=")
|
||||
]
|
||||
|
||||
return lines[0].split("=")[1]
|
||||
|
||||
|
||||
def verify_evidence(oe_binary_path, evidence_path):
|
||||
# Until https://github.com/microsoft/CCF/issues/1468 is done, CCF
|
||||
# uses old attestation API to generate quotes
|
||||
report_format = "LEGACY_REPORT_REMOTE"
|
||||
res = subprocess.run(
|
||||
[
|
||||
os.path.join(oe_binary_path, "oeverify"),
|
||||
"-f",
|
||||
report_format,
|
||||
"-r",
|
||||
evidence_path,
|
||||
],
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
lines = [
|
||||
line
|
||||
for line in res.stdout.decode().split(os.linesep)
|
||||
if line.startswith("Enclave unique_id: ")
|
||||
]
|
||||
|
||||
return lines[0].split("0x")[1]
|
||||
|
||||
|
||||
@reqs.description("Verify node evidence")
|
||||
def test_verify_quotes(network, args):
|
||||
if args.enclave_type == "virtual":
|
||||
LOG.warning("Skipping quote test with virtual enclave")
|
||||
return network
|
||||
|
||||
for node in network.get_joined_nodes():
|
||||
with tempfile.NamedTemporaryFile() as nf:
|
||||
with node.client() as c:
|
||||
r = c.get("/node/quote")
|
||||
raw_quote = bytes.fromhex(r.body.json()["raw"])
|
||||
mrenclave = r.body.json()["mrenclave"]
|
||||
nf.write(raw_quote)
|
||||
nf.flush()
|
||||
result = verify_evidence(args.oe_binary, nf.name)
|
||||
assert (
|
||||
mrenclave == result
|
||||
), f"/node/quote mrenclave does not match quote mrenclave for node {node.node_id}"
|
||||
|
||||
return network
|
||||
|
||||
|
||||
@reqs.description("Update all nodes code")
|
||||
def test_update_all_nodes(network, args):
|
||||
primary, _ = network.find_nodes()
|
||||
|
||||
first_code_id = get_code_id(
|
||||
args.oe_binary, infra.path.build_lib_path(args.package, args.enclave_type)
|
||||
)
|
||||
|
||||
with primary.client() as uc:
|
||||
r = uc.get("/node/code")
|
||||
assert r.body.json() == {
|
||||
"versions": [{"digest": first_code_id, "status": "ACCEPTED"}],
|
||||
}, r.body
|
||||
|
||||
LOG.info("Adding a new node")
|
||||
new_node = network.create_and_trust_node(args.package, "localhost", args)
|
||||
assert new_node
|
||||
|
||||
new_code_id = get_code_id(
|
||||
args.oe_binary,
|
||||
infra.path.build_lib_path(args.patched_file_name, args.enclave_type),
|
||||
)
|
||||
|
||||
LOG.info(f"Adding a node with unsupported code id {new_code_id}")
|
||||
code_not_found_exception = None
|
||||
try:
|
||||
network.create_and_add_pending_node(
|
||||
args.patched_file_name, "localhost", args, timeout=3
|
||||
)
|
||||
except infra.network.CodeIdNotFound as err:
|
||||
code_not_found_exception = err
|
||||
|
||||
assert (
|
||||
code_not_found_exception is not None
|
||||
), f"Adding a node with unsupported code id {new_code_id} should fail"
|
||||
|
||||
# Slow quote verification means that any attempt to add a node may cause an election, so confirm primary after adding node
|
||||
primary, _ = network.find_primary()
|
||||
|
||||
network.consortium.add_new_code(primary, new_code_id)
|
||||
|
||||
with primary.client() as uc:
|
||||
r = uc.get("/node/code")
|
||||
versions = sorted(r.body.json()["versions"], key=lambda x: x["digest"])
|
||||
expected = sorted(
|
||||
[
|
||||
{"digest": first_code_id, "status": "ACCEPTED"},
|
||||
{"digest": new_code_id, "status": "ACCEPTED"},
|
||||
],
|
||||
key=lambda x: x["digest"],
|
||||
)
|
||||
assert versions == expected, versions
|
||||
|
||||
new_nodes = set()
|
||||
old_nodes_count = len(network.nodes)
|
||||
new_nodes_count = old_nodes_count + 1
|
||||
|
||||
LOG.info(
|
||||
f"Adding more new nodes ({new_nodes_count}) than originally existed ({old_nodes_count})"
|
||||
)
|
||||
for _ in range(0, new_nodes_count):
|
||||
new_node = network.create_and_trust_node(
|
||||
args.patched_file_name, "localhost", args
|
||||
)
|
||||
assert new_node
|
||||
new_nodes.add(new_node)
|
||||
|
||||
LOG.info("Stopping all original nodes")
|
||||
old_nodes = set(network.nodes).difference(new_nodes)
|
||||
for node in old_nodes:
|
||||
LOG.debug(f"Stopping old node {node.node_id}")
|
||||
node.stop()
|
||||
|
||||
new_primary, _ = network.wait_for_new_primary(primary.node_id)
|
||||
LOG.info(f"New_primary is {new_primary.node_id}")
|
||||
|
||||
LOG.info("Adding another node to the network")
|
||||
new_node = network.create_and_trust_node(args.patched_file_name, "localhost", args)
|
||||
assert new_node
|
||||
network.wait_for_node_commit_sync()
|
||||
|
||||
LOG.info("Remove first code id")
|
||||
network.consortium.retire_code(new_node, first_code_id)
|
||||
|
||||
with new_node.client() as uc:
|
||||
r = uc.get("/node/code")
|
||||
versions = sorted(r.body.json()["versions"], key=lambda x: x["digest"])
|
||||
expected = sorted(
|
||||
[
|
||||
{"digest": first_code_id, "status": "RETIRED"},
|
||||
{"digest": new_code_id, "status": "ACCEPTED"},
|
||||
],
|
||||
key=lambda x: x["digest"],
|
||||
)
|
||||
assert versions == expected, versions
|
||||
|
||||
LOG.info(f"Adding a node with retired code id {first_code_id}")
|
||||
code_not_found_exception = None
|
||||
try:
|
||||
network.create_and_add_pending_node(args.package, "localhost", args, timeout=3)
|
||||
except infra.network.CodeIdRetired as err:
|
||||
code_not_found_exception = err
|
||||
|
||||
assert (
|
||||
code_not_found_exception is not None
|
||||
), f"Adding a node with unsupported code id {new_code_id} should fail"
|
||||
|
||||
LOG.info("Adding another node with the new code to the network")
|
||||
new_node = network.create_and_trust_node(args.patched_file_name, "localhost", args)
|
||||
assert new_node
|
||||
network.wait_for_node_commit_sync()
|
||||
|
||||
|
||||
def run(args):
|
||||
hosts = ["localhost", "localhost"]
|
||||
|
||||
|
@ -30,130 +194,14 @@ def run(args):
|
|||
hosts, args.binary_dir, args.debug_nodes, args.perf_nodes, pdb=args.pdb
|
||||
) as network:
|
||||
network.start_and_join(args)
|
||||
primary, _ = network.find_nodes()
|
||||
|
||||
first_code_id = get_code_id(
|
||||
infra.path.build_lib_path(args.package, args.enclave_type)
|
||||
)
|
||||
|
||||
with primary.client() as uc:
|
||||
r = uc.get("/node/code")
|
||||
assert r.body.json() == {
|
||||
"versions": [{"digest": first_code_id, "status": "ACCEPTED"}],
|
||||
}, r.body
|
||||
|
||||
LOG.info("Adding a new node")
|
||||
new_node = network.create_and_trust_node(args.package, "localhost", args)
|
||||
assert new_node
|
||||
|
||||
new_code_id = get_code_id(
|
||||
infra.path.build_lib_path(args.patched_file_name, args.enclave_type)
|
||||
)
|
||||
|
||||
LOG.info(f"Adding a node with unsupported code id {new_code_id}")
|
||||
code_not_found_exception = None
|
||||
try:
|
||||
network.create_and_add_pending_node(
|
||||
args.patched_file_name, "localhost", args, timeout=3
|
||||
)
|
||||
except infra.network.CodeIdNotFound as err:
|
||||
code_not_found_exception = err
|
||||
|
||||
assert (
|
||||
code_not_found_exception is not None
|
||||
), f"Adding a node with unsupported code id {new_code_id} should fail"
|
||||
|
||||
# Slow quote verification means that any attempt to add a node may cause an election, so confirm primary after adding node
|
||||
primary, _ = network.find_primary()
|
||||
|
||||
network.consortium.add_new_code(primary, new_code_id)
|
||||
|
||||
with primary.client() as uc:
|
||||
r = uc.get("/node/code")
|
||||
versions = sorted(r.body.json()["versions"], key=lambda x: x["digest"])
|
||||
expected = sorted(
|
||||
[
|
||||
{"digest": first_code_id, "status": "ACCEPTED"},
|
||||
{"digest": new_code_id, "status": "ACCEPTED"},
|
||||
],
|
||||
key=lambda x: x["digest"],
|
||||
)
|
||||
assert versions == expected, versions
|
||||
|
||||
new_nodes = set()
|
||||
old_nodes_count = len(network.nodes)
|
||||
new_nodes_count = old_nodes_count + 1
|
||||
|
||||
LOG.info(
|
||||
f"Adding more new nodes ({new_nodes_count}) than originally existed ({old_nodes_count})"
|
||||
)
|
||||
for _ in range(0, new_nodes_count):
|
||||
new_node = network.create_and_trust_node(
|
||||
args.patched_file_name, "localhost", args
|
||||
)
|
||||
assert new_node
|
||||
new_nodes.add(new_node)
|
||||
|
||||
LOG.info("Stopping all original nodes")
|
||||
old_nodes = set(network.nodes).difference(new_nodes)
|
||||
for node in old_nodes:
|
||||
LOG.debug(f"Stopping old node {node.node_id}")
|
||||
node.stop()
|
||||
|
||||
new_primary, _ = network.wait_for_new_primary(primary.node_id)
|
||||
LOG.info(f"New_primary is {new_primary.node_id}")
|
||||
|
||||
LOG.info("Adding another node to the network")
|
||||
new_node = network.create_and_trust_node(
|
||||
args.patched_file_name, "localhost", args
|
||||
)
|
||||
assert new_node
|
||||
network.wait_for_node_commit_sync()
|
||||
|
||||
LOG.info("Remove first code id")
|
||||
network.consortium.retire_code(new_node, first_code_id)
|
||||
|
||||
with new_node.client() as uc:
|
||||
r = uc.get("/node/code")
|
||||
versions = sorted(r.body.json()["versions"], key=lambda x: x["digest"])
|
||||
expected = sorted(
|
||||
[
|
||||
{"digest": first_code_id, "status": "RETIRED"},
|
||||
{"digest": new_code_id, "status": "ACCEPTED"},
|
||||
],
|
||||
key=lambda x: x["digest"],
|
||||
)
|
||||
assert versions == expected, versions
|
||||
|
||||
LOG.info(f"Adding a node with retired code id {first_code_id}")
|
||||
code_not_found_exception = None
|
||||
try:
|
||||
network.create_and_add_pending_node(
|
||||
args.package, "localhost", args, timeout=3
|
||||
)
|
||||
except infra.network.CodeIdRetired as err:
|
||||
code_not_found_exception = err
|
||||
|
||||
assert (
|
||||
code_not_found_exception is not None
|
||||
), f"Adding a node with unsupported code id {new_code_id} should fail"
|
||||
|
||||
LOG.info("Adding another node with the new code to the network")
|
||||
new_node = network.create_and_trust_node(
|
||||
args.patched_file_name, "localhost", args
|
||||
)
|
||||
assert new_node
|
||||
network.wait_for_node_commit_sync()
|
||||
test_verify_quotes(network, args)
|
||||
test_update_all_nodes(network, args)
|
||||
test_verify_quotes(network, args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
def add(parser):
|
||||
parser.add_argument(
|
||||
"--oesign", help="Path to oesign binary", type=str, required=True
|
||||
)
|
||||
|
||||
args = infra.e2e_args.cli_args(add)
|
||||
args = infra.e2e_args.cli_args()
|
||||
if args.enclave_type == "virtual":
|
||||
LOG.warning("Skipping code update test with virtual enclave")
|
||||
sys.exit()
|
||||
|
|
|
@ -22,7 +22,7 @@ def test_quote(network, args, verify=True):
|
|||
with primary.client() as c:
|
||||
oed = subprocess.run(
|
||||
[
|
||||
args.oesign,
|
||||
os.path.join(args.oe_binary, "oesign"),
|
||||
"dump",
|
||||
"-e",
|
||||
infra.path.build_lib_path(args.package, args.enclave_type),
|
||||
|
@ -38,11 +38,9 @@ def test_quote(network, args, verify=True):
|
|||
expected_mrenclave = lines[0].strip().split("=")[1]
|
||||
|
||||
r = c.get("/node/quote")
|
||||
quotes = r.body.json()["quotes"]
|
||||
assert len(quotes) == 1
|
||||
primary_quote = quotes[0]
|
||||
assert primary_quote["node_id"] == 0
|
||||
primary_mrenclave = primary_quote["mrenclave"]
|
||||
primary_quote_info = r.body.json()
|
||||
assert primary_quote_info["node_id"] == 0
|
||||
primary_mrenclave = primary_quote_info["mrenclave"]
|
||||
assert primary_mrenclave == expected_mrenclave, (
|
||||
primary_mrenclave,
|
||||
expected_mrenclave,
|
||||
|
@ -134,14 +132,7 @@ def run(args):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
def add(parser):
|
||||
parser.add_argument(
|
||||
"--oesign", help="Path oesign binary", type=str, required=True
|
||||
)
|
||||
|
||||
args = infra.e2e_args.cli_args(add=add)
|
||||
|
||||
args = infra.e2e_args.cli_args()
|
||||
if args.enclave_type == "virtual":
|
||||
LOG.warning("This test can only run in real enclaves, skipping")
|
||||
sys.exit(0)
|
||||
|
|
|
@ -34,6 +34,12 @@ def cli_args(add=lambda x: None, parser=None, accept_unknown=False):
|
|||
help="Path to CCF binaries (cchost, scurl, keygenerator)",
|
||||
default=".",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--oe-binary",
|
||||
help="Path to Open Enclave binary folder",
|
||||
type=str,
|
||||
default="/opt/openenclave/bin/",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--debug-nodes",
|
||||
|
|
|
@ -8,6 +8,7 @@ import reconfiguration
|
|||
import recovery
|
||||
import rekey
|
||||
import election
|
||||
import code_update
|
||||
|
||||
from inspect import signature, Parameter
|
||||
|
||||
|
@ -98,6 +99,8 @@ all_tests_suite = [
|
|||
# election:
|
||||
reconfiguration.test_add_node,
|
||||
election.test_kill_primary,
|
||||
# code update:
|
||||
code_update.test_verify_quotes,
|
||||
]
|
||||
suites["all"] = all_tests_suite
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче