Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microsoft CCF based PDO transaction processor #259

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "interpreters/wasm-micro-runtime"]
path = interpreters/wasm-micro-runtime
url = https://github.com/bytecodealliance/wasm-micro-runtime.git
[submodule "ccf_transaction_processor/CCF"]
path = ccf_transaction_processor/CCF
url = https://github.com/microsoft/CCF.git
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ smart contracts policies are enforced through execution in a Trusted Execution
Environment (TEE).

PDO uses a distributed ledger, in this case the
[Hyperledger Sawtooth](httphttps://sawtooth.hyperledger.org/)
[Hyperledger Sawtooth](https://sawtooth.hyperledger.org/)
distributed ledger, to ensure that there is a single, authoritative
instance of the object, and to provide a means of guaranteeing atomicity of
updates across interacting objects. The long-term goal for PDO is to perform
contract execution and storage off the blockchain, with only a hash of
blockchain state stored on the distributed ledger
updates across interacting objects. PDO performs contract execution and storage off the blockchain, with only a hash of
blockchain state stored on the distributed ledger.

There is also an ongoing experimental effort to add support for
[Microsoft Confidential Consortium Framework (CCF)](https://microsoft.github.io/CCF/) based ledger.
Currently, the PDO/CCF combo is restricted to virtual enclaves, and lacks docker as well as
automated test support.

PDO provides benefits for both application developers seeking to define and
implement privacy-preserving distributed ledgers, and for service providers
Expand Down
21 changes: 18 additions & 3 deletions build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ ifndef SGX_MODE
$(error Incomplete configuration, SGX_MODE is not defined)
endif

ifndef PDO_LEDGER_TYPE
$(error Incomplete configuration, PDO_LEDGER_TYPE is not defined)
endif

SCRIPTDIR ?= $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
DSTDIR ?= $(PDO_INSTALL_ROOT)
SRCDIR ?= $(abspath $(SCRIPTDIR)/..)
Expand Down Expand Up @@ -86,6 +90,11 @@ $(PYTHON_DIR) :
. $(abspath $(DSTDIR)/bin/activate) ; pip install --upgrade cryptography
. $(abspath $(DSTDIR)/bin/activate) ; pip install --upgrade pyparsing
. $(abspath $(DSTDIR)/bin/activate) ; pip install --upgrade lmdb
. $(abspath $(DSTDIR)/bin/activate) ; pip install --upgrade loguru
. $(abspath $(DSTDIR)/bin/activate) ; pip install --upgrade requests_http_signature
. $(abspath $(DSTDIR)/bin/activate) ; pip install --upgrade websocket-client
. $(abspath $(DSTDIR)/bin/activate) ; pip install --upgrade msgpack


$(DSTDIR) :
@echo CREATE INSTALLATION DIRECTORY $(DSTDIR)
Expand All @@ -111,7 +120,13 @@ ${PDO_ENCLAVE_CODE_SIGN_PEM} :
openssl genrsa -3 -out ${PDO_ENCLAVE_CODE_SIGN_PEM} 3072

service_indexes := 1 2 3 4 5
ESERVICE_SKF := $(addprefix $(KEYDIR),$(foreach i,$(service_indexes),eservice$(i)_private.skf))

ifeq ($(PDO_LEDGER_TYPE),sawtooth)
ESERVICE_KEYS := $(addprefix $(KEYDIR),$(foreach i,$(service_indexes),eservice$(i)_private.skf))
else
ESERVICE_KEYS := $(addprefix $(KEYDIR),$(foreach i,$(service_indexes),eservice$(i)_private.pem))
endif

SSERVICE_PEM := $(addprefix $(KEYDIR),$(foreach i,$(service_indexes),sservice$(i)_private.pem))
PSERVICE_PEM := $(addprefix $(KEYDIR),$(foreach i,$(service_indexes),pservice$(i)_private.pem))

Expand All @@ -124,7 +139,7 @@ USER_PEM := $(addprefix $(KEYDIR),$(foreach i,$(user_indexes),user$(i)_private.p
%.pem :
. $(abspath $(DSTDIR)/bin/activate) ; $(KEYGEN) --keyfile $(subst _private,,$*) --format pem

keys : $(ESERVICE_SKF) $(SSERVICE_PEM) $(PSERVICE_PEM) $(USER_PEM)
keys : $(ESERVICE_KEYS) $(SSERVICE_PEM) $(PSERVICE_PEM) $(USER_PEM)

ESERVICE_CONF := $(ETCDIR)/eservice1.toml
SSERVICE_CONF := $(ETCDIR)/sservice1.toml
Expand Down Expand Up @@ -185,7 +200,7 @@ template : $(PYTHON_DIR)
mkdir -p $(DSTDIR)/opt/pdo/data
mkdir -p $(DSTDIR)/opt/pdo/etc
mkdir -p $(DSTDIR)/opt/pdo/etc/keys/sgx
mkdir -p $(DSTDIR)/opt/pdo/etc/keys/sawtooth
mkdir -p $(DSTDIR)/opt/pdo/etc/keys/ledger
mkdir -p $(DSTDIR)/opt/pdo/keys
mkdir -p $(DSTDIR)/opt/pdo/logs

Expand Down
12 changes: 12 additions & 0 deletions build/__tools__/expand-config
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,22 @@ import pdo.common.config as pconfig
try :
ContractHome = os.environ["PDO_HOME"]
LedgerURL = os.environ["PDO_LEDGER_URL"]
LedgerType = os.environ["PDO_LEDGER_TYPE"]
SPID = os.environ["PDO_SPID"]
SPID_API_KEY = os.environ["PDO_SPID_API_KEY"]
except KeyError as ke :
print("incomplete configuration, missing definition of {0}".format(str(ke)))
sys.exit(-1)

#deduce eservice key format based on ledger type
if LedgerType == 'sawtooth':
EserviceKeyFormat = 'skf'
elif LedgerType == 'ccf':
EserviceKeyFormat = 'pem'
else:
print("Cannot configure eservice keys. Invalid ledger type, Must be 'sawtooth' or 'ccf'" )
sys.exit(-1)

ContractHost = os.environ.get("HOSTNAME", "localhost")
ContractEtc = os.path.join(ContractHome, "etc")
ContractKeys = os.path.join(ContractHome, "keys")
Expand All @@ -50,6 +60,8 @@ config_map = {
'keys' : ContractKeys,
'logs' : ContractLogs,
'ledger' : LedgerURL,
'ledger_type': LedgerType,
'eservice_key_format': EserviceKeyFormat,
'proxy' : HttpsProxy,
'spid' : SPID,
'spid_api_key' : SPID_API_KEY
Expand Down
33 changes: 20 additions & 13 deletions build/common-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,16 @@ var_set() {

env_val[PDO_LEDGER_URL]="${PDO_LEDGER_URL:-http://127.0.0.1:8008}"
env_desc[PDO_LEDGER_URL]="
PDO_PDO_LEDGER_URL is the URL is to submit transactions to the
Sawtooth ledger.
PDO_LEDGER_URL is the URL is to submit transactions to the ledger.
"
env_key_sort[$i]="PDO_LEDGER_URL"; i=$i+1; export PDO_LEDGER_URL=${env_val[PDO_LEDGER_URL]}

env_val[PDO_LEDGER_TYPE]="${PDO_LEDGER_TYPE:-sawtooth}"
env_desc[PDO_LEDGER_TYPE]="
PDO_LEDGER_TYPE is the ledger used by PDO. Choose either sawtooth or ccf
"
env_key_sort[$i]="PDO_LEDGER_TYPE"; i=$i+1; export PDO_LEDGER_TYPE=${env_val[PDO_LEDGER_TYPE]}

env_val[PDO_INSTALL_ROOT]="${PDO_INSTALL_ROOT:-${SCRIPTDIR}/_dev}"
env_desc[PDO_INSTALL_ROOT]="
PDO_INSTALL_ROOT is the root of the directory in which the virtual
Expand Down Expand Up @@ -130,19 +135,20 @@ var_set() {
"
env_key_sort[$i]="PDO_SPID_API_KEY"; i=$i+1; export PDO_SPID_API_KEY=${env_val[PDO_SPID_API_KEY]}

env_val[PDO_STL_KEY_ROOT]="${PDO_STL_KEY_ROOT:-${PDO_INSTALL_ROOT}/opt/pdo/etc/keys/sawtooth}"
env_desc[PDO_STL_KEY_ROOT]="
PDO_STL_KEY_ROOT is the root directory where the system keys are stored
for Sawtooth integration; files in this directory
are not automatically generated.
env_val[PDO_LEDGER_KEY_ROOT]="${PDO_LEDGER_KEY_ROOT:-${PDO_INSTALL_ROOT}/opt/pdo/etc/keys/ledger}"
env_desc[PDO_LEDGER_KEY_ROOT]="
PDO_LEDGER_KEY_ROOT is the root directory where the system keys are stored
for ledger integration; files in this directory are not automatically generated. When ccf is used
as ledger, the ccf keys {networkcert.pem, userccf_cert.pem, userccf_privk.pem} must be
placed under this folder. These keys get generated during ccf deployment.
"
env_key_sort[$i]="PDO_STL_KEY_ROOT"; i=$i+1; export PDO_STL_KEY_ROOT=${env_val[PDO_STL_KEY_ROOT]}
env_key_sort[$i]="PDO_LEDGER_KEY_ROOT"; i=$i+1; export PDO_LEDGER_KEY_ROOT=${env_val[PDO_LEDGER_KEY_ROOT]}

env_val[PDO_LEDGER_KEY_SKF]="${PDO_LEDGER_KEY_SKF:-${PDO_STL_KEY_ROOT}/pdo_validator.priv}"
env_val[PDO_LEDGER_KEY_SKF]="${PDO_LEDGER_KEY_SKF:-${PDO_LEDGER_KEY_ROOT}/pdo_validator.priv}"
env_desc[PDO_LEDGER_KEY_SKF]="
PDO_LEDGER_KEY_SKF is used to update settings in the Sawtooth validator.
This is the key used by the Sawtooth ledger and is generally
found in the file .sawtooth/keys/sawtooth.priv in the
found in the file .sawtooth/keys/ledger.priv in the
Sawtooth installation directory hiearchy.
"
env_key_sort[$i]="PDO_LEDGER_KEY_SKF"; i=$i+1; export PDO_LEDGER_KEY_SKF=${env_val[PDO_LEDGER_KEY_SKF]}
Expand Down Expand Up @@ -172,16 +178,17 @@ in the build, installation & execution process. While the build should
progress with only the default values specified, commonly five variables
are set and then this file is evaluated. These five variables are:
WASM_SRC, TINY_SCHEME_SRC, PDO_LEDGER_URL, PDO_INSTALL_ROOT, and
PDO_STL_KEY_ROOT. In case you run in SGX HW mode you usally will define
PDO_LEDGER_KEY_ROOT. In case you run in SGX HW mode you usally will define
PDO_SGX_KEY_ROOT. See further down information on these variables and
others you could override from defaults.

The default usage of this script is to be sourced. For example,
local configuration file may be constructed as:

export PDO_STL_KEY_ROOT=${HOME}/keys
export PDO_LEDGER_KEY_ROOT=${HOME}/keys/ledger
export PDO_INSTALL_ROOT=${HOME}/pdo-test-env
export PDO_LEDGER_URL=http://127.0.0.1:8008
export PDO_LEDGER_TYPE=sawtooth
export TINY_SCHEME_SRC=${HOME}/tinyscheme-1.41
export WASM_SRC=${HOME}/wasm

Expand Down Expand Up @@ -216,7 +223,7 @@ do
case $opt in
--reset-keys|-r)
# -----------------------------------------------------------------
# if you change either PDO_SGX_KEY_ROOT or PDO_STL_KEY_ROOT variable
# if you change either PDO_SGX_KEY_ROOT or PDO_LEDGER_KEY_ROOT variable
# and re-source this file you should unset all of the variables that
# depend on those variables
# -----------------------------------------------------------------
Expand Down
7 changes: 4 additions & 3 deletions build/opt/pdo/etc/template/eservice.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ URL = "http://localhost:${{7200+_count_}}"
BlockStore = "${data}/${{identity.replace('eservice','sservice')}}.mdb"

# --------------------------------------------------
# Sawtooth -- sawtooth ledger configuration
# Ledger -- ledger configuration
# --------------------------------------------------
[Sawtooth]
[Ledger]
# LedgerURL is used to submit the registration transaction should
# the enclave require registration
LedgerType = "${ledger_type}"
LedgerURL = "${ledger}"
Organization = "Widgets R Us"

Expand All @@ -54,7 +55,7 @@ LogFile = "${logs}/${identity}.log"
# Keys are used to sign the registration transaction
# should it be required
SearchPath = [ ".", "./keys", "${keys}" ]
FileName = "${identity}_private.skf"
FileName = "${identity}_private.${eservice_key_format}"

# --------------------------------------------------
# EnclaveData -- configuration of sealed storage for the enclave
Expand Down
8 changes: 6 additions & 2 deletions build/opt/pdo/etc/template/pcontract.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@
Identity = "${identity}"

# --------------------------------------------------
# Sawtooth -- sawtooth ledger configuration
# Ledger -- ledger configuration
# --------------------------------------------------
[Sawtooth]
[Ledger]
# LedgerURL is used to submit the registration transaction should
# the enclave require registration
LedgerType = "${ledger_type}"
LedgerURL = "${ledger}"
Organization = "Widgets R Us"

# --------------------------------------------------
# Service -- Information about enclave/provisioning services
Expand Down
8 changes: 6 additions & 2 deletions build/opt/pdo/etc/template/pservice.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ HttpPort = ${{7000+_count_}}
Host = "localhost"

# --------------------------------------------------
# Sawtooth -- sawtooth ledger configuration
# Ledger -- ledger configuration
# --------------------------------------------------
[Sawtooth]
[Ledger]
# LedgerURL is used to submit the registration transaction should
# the enclave require registration
LedgerType = "${ledger_type}"
LedgerURL = "${ledger}"
Organization = "Widgets R Us"

# --------------------------------------------------
# Logging -- configuration of service logging
Expand Down
1 change: 1 addition & 0 deletions ccf_transaction_processor/CCF
Submodule CCF added at 80476b
42 changes: 42 additions & 0 deletions ccf_transaction_processor/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!---
Licensed under Creative Commons Attribution 4.0 International License
https://creativecommons.org/licenses/by/4.0/
--->

## Microsoft CCF based PDO Transaction Processor

This folder contains software for PDO transaction processor (TP) based on Microsoft's CCF blockchain.
The software is located under transaction_processor/. The folder CCF/ points to CCF tag 0.7.1 which is
included as a submodule under the PDO repo. The TP software is written and tested for CCF tag 0.7.1.
Compatability with other CCF versions is not guaranteed.

The TP must viewed as a CCF application. Documentation for building and deploying CCF applications
prakashngit marked this conversation as resolved.
Show resolved Hide resolved
can be found at https://microsoft.github.io/CCF/. The CCF legder that stores the PDO TP registries is
encrypted, and is accessible only within CCF encalves. Currently PDO/CCF combination is supported
only under the virtual enclave mode for both PDO and CCF. (set env variable SGX_MODE=SIM for PDO &
masomel marked this conversation as resolved.
Show resolved Hide resolved
set cmake flag TARGET=virtual for ccf). Support for HW mode for both PDO and CCF will be added soon. Further,
the current implementation of PDO TP hasn't been tested under multi-threaded CCF enclaves.(CCF 0.7.1 offers initial support for multi-threading). It is recommended that the application is deployed with single worker thread per enclave. Please see https://microsoft.github.io/CCF/developers/threading.html for instructions.

CCF uses mutually authenticated TLS channels for transactions. Given that in PDO client authentication is implemented within the transaction processor itself, we do not utilize the client authentication feature provided by CCF. Once CCF is deployed, CCF's network certificate (networkcert.pem) and one set of user keys (userccf_cert.pem & userccf_privk.pem) must be made available to all PDO processes that want to submit a CCF transaction. In this case, every PDO process behaves as though it is a CCF user corresponding to the private key userccf_privk.pem.
These keys must be stored under $PDO_LEDGER_KEY_ROOT as part of PDO deployment.

It may be noted that PDO also supports TP based on the Hyperledger Sawtooth blockchain.
As far as PDO is concerned, CCF based TP is functionally identical to the Sawtooth based
TP (except for one additional feature described below). A key difference beween the two ledgers
prakashngit marked this conversation as resolved.
Show resolved Hide resolved
is the fact that while the ledger in CCF is encrypted as noted above, the ledger is Sawtooth is stored in plain text.
Even though the no part of conract state gets stored in the ledger in both CCF & Sawtooth, encrypting the
ledger as in CCF helps to hide transaction patterns that are otherwise visible in Sawtooth ledger. Detailed documentation about Sawtooth based TP can be found at $PDO_SRC/sawtooth/docs. The schema for JSON payloads used to submit CCF transactions can be found at [${PDO_SRC}/python/pdo/submitter/ccf/docs/](../python/pdo/submitter/ccf/docs/ccf_payload_schema.json). For additional references to documentation about PDO, including transaction processor protocols, see [${PDO_SRC}/README.md](../README.md)

A feature of the CCF based TP that is not supported by Sawtooth based TP is the fact that
prakashngit marked this conversation as resolved.
Show resolved Hide resolved
responses to read-transactions include a payload signature, where the signature is generated by the CCF enclave
serving the read request. The (signing key, verifying key) pair is created within the TP,
and is globally persisted among all CCF enclaves. The verifying_key can be obtained from CCF using
the "get_ledger_verifying_key" transaction. This feature may be used by PDO clients to establish offline verifiable proof of transaction commits as desired by the PDO smart contract application. Note that for trust purposes, it is recommended that any entity that uses the above verifying_key gets it directly from the CCF service using the
"get_ledger_verifying_key" transaction.

We note that the very first invocation of "get_ledger_verifying_key" rpc
after the service is started is used to create the key pair, which will then be globally committed.
The system admin who deploys the CCF ledger is expected to invoke the "get_ledger_verifying_key"
rpc after deployment to generate these keys. Further, the admin must ensure that this key pair is globally committed
before making the ledger available for PDO usage. This can checked by issuing the rpc again & ensuring that a verifying key gets returned. See https://microsoft.github.io/CCF/users/issue_commands.html for instructions on
how an rpc can be issued via command line.
Loading