diff --git a/core/genesis.go b/core/genesis.go index 56b88b761..9b5a373fa 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -169,8 +169,12 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig if genesis.Config.TransactionSizeLimit == 0 { genesis.Config.TransactionSizeLimit = DefaultTxPoolConfig.TransactionSizeLimit } + // Set default contract size limit that can be deployed if not set in genesis + if genesis.Config.MaxCodeSize == 0 { + genesis.Config.MaxCodeSize = DefaultTxPoolConfig.MaxCodeSize + } - // Check transaction size limit + // Check transaction size limit and max contract code size err := genesis.Config.IsValid() if err != nil { return genesis.Config, common.Hash{}, err diff --git a/core/genesis_test.go b/core/genesis_test.go index d353b3866..0e3b35466 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -90,11 +90,23 @@ func TestSetupGenesis(t *testing.T) { name: "genesis with incorrect SizeLimit", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { customg.Config.TransactionSizeLimit = 100000 + customg.Config.MaxCodeSize = 32 return SetupGenesisBlock(db, &customg) }, wantErr: errors.New("Genesis transaction size limit must be between 32 and 128"), wantConfig: customg.Config, }, + { + name: "genesis with incorrect max code size ", + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + customg.Config.TransactionSizeLimit = 64 + customg.Config.MaxCodeSize = 100000 + return SetupGenesisBlock(db, &customg) + }, + wantErr: errors.New("Genesis max code size must be between 24 and 128"), + wantConfig: customg.Config, + }, + // { // name: "custom block in DB, genesis == nil", // fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { diff --git a/core/tx_pool.go b/core/tx_pool.go index 2b4f7a51a..fa984db15 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -135,6 +135,7 @@ type TxPoolConfig struct { Rejournal time.Duration // Time interval to regenerate the local transaction journal TransactionSizeLimit uint64 // Maximum size allowed for valid transaction (in KB) + MaxCodeSize uint64 // Maximum size allowed of contract code that can be deployed (in KB) PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce) @@ -154,6 +155,7 @@ var DefaultTxPoolConfig = TxPoolConfig{ Rejournal: time.Hour, TransactionSizeLimit: 64, + MaxCodeSize: 24, PriceLimit: 1, PriceBump: 10, diff --git a/core/vm/evm.go b/core/vm/evm.go index aaebfb5ce..0135ace7b 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -487,8 +487,16 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, ret, err := run(evm, contract, nil, false) - // check whether the max code size has been exceeded - maxCodeSizeExceeded := evm.ChainConfig().IsEIP158(evm.BlockNumber) && len(ret) > params.MaxCodeSize + var maxCodeSize int + if evm.ChainConfig().MaxCodeSize > 0 { + maxCodeSize = int(evm.ChainConfig().MaxCodeSize * 1024) + } else { + maxCodeSize = params.MaxCodeSize + } + + // check whether the max code size has been exceeded, check maxcode size from chain config + // maxCodeSizeExceeded := evm.ChainConfig().IsEIP158(evm.BlockNumber) && len(ret) > params.MaxCodeSize + maxCodeSizeExceeded := evm.ChainConfig().IsEIP158(evm.BlockNumber) && len(ret) > maxCodeSize // if the contract creation ran successfully and no errors were returned // calculate the gas required to store the code. If the code could not // be stored due to not enough gas set an error and let it be handled @@ -580,6 +588,8 @@ func (env *EVM) Push(statedb StateDB) { // Quorum : the read only depth to be set up only once for the entire // op code execution. This will be set first time transition from // private state to public state happens + // statedb will be the state of the contract being called. + // if a private contract is calling a public contract make it readonly. if !env.quorumReadOnly && env.privateState != statedb { env.quorumReadOnly = true env.readOnlyDepth = env.currentStateDepth diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 3440de3c4..24f5c41bf 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -207,10 +207,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // Get the memory location of pc op = contract.GetOp(pc) - if in.evm.quorumReadOnly && op.isMutating() { - return nil, fmt.Errorf("VM in read-only mode. Mutating opcode prohibited") - } - if in.cfg.Debug { // Capture pre-execution values for tracing. logged, pcCopy, gasCopy = false, pc, contract.Gas @@ -222,6 +218,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( if !operation.valid { return nil, fmt.Errorf("invalid opcode 0x%x", int(op)) } + if in.evm.quorumReadOnly && operation.writes { + return nil, fmt.Errorf("VM in read-only mode. Mutating opcode prohibited") + } if err := operation.validateStack(stack); err != nil { return nil, err } diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index 549458581..4349ffd29 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -538,13 +538,3 @@ var stringToOp = map[string]OpCode{ func StringToOp(str string) OpCode { return stringToOp[str] } - -func (op OpCode) isMutating() bool { - switch op { - // TODO(joel): REVERT? - case SELFDESTRUCT, CREATE, SSTORE, LOG0, LOG1, LOG2, LOG3, LOG4: - return true - default: - return false - } -} diff --git a/docs/Cakeshop/Cakeshop FAQ.md b/docs/Cakeshop/Cakeshop FAQ.md new file mode 100644 index 000000000..7c8627865 --- /dev/null +++ b/docs/Cakeshop/Cakeshop FAQ.md @@ -0,0 +1,30 @@ +??? question "How do I call contracts or send Transactions to existing contracts?" + + The "Sandbox" tab provides the ability to load up a contract that has been deployed using Cakeshop or the Cakeshop APIs and to make Read calls or submit Transactions to those contracts. + + +??? question "How do I find existing contracts?" + + The "Contracts" explorer tab lists all contracts that have been deployed using Cakeshop sandbox. + +??? question "How do I deploy contracts to my network using Cakeshop?" + + The "Sandbox" tab provides the ability to write and deploy contracts onto your chain. + +??? question "How do I run Cakeshop on any Ethereum build or on my private Ethereum network?" + + See the [Attach Mode](../Getting Started#attach-mode) instructions for using Cakeshop with your Ethereum-like node. This provides you the ability to start Cakeshop without auto-starting a geth node, and then attach it to your already-running node. + +??? question "How do I run Cakeshop on many nodes?" + + See the [Multi-Instance](../Getting Started#multi-instance-setup) instructions for managing multiple nodes that you control on an Ethereum-based network. + +??? question "How do I save the solidity files that I have written in the Sandbox?" + + You can't explicitly save these files at the moment, but they are auto-saved to your browser cache. For this reason, you shouldn't use Cakeshop as your version management system and you should definitely ensure you save them in a proper VCS outside of Cakeshop. + +??? question "What is an 'Ethereum-like' ledger/node?" + + An 'Ethereum-like' ledger/node is one that uses the Ethereum JSON RPC API. The Ethereum clients and [Quorum](https://github.com/jpmorganchase/quorum) are examples. + + Note that if an Ethereum-forked ledger forks too far away from base Ethereum then there may be some issues with using Cakeshop on top of it. diff --git a/docs/Cakeshop/Getting started.md b/docs/Cakeshop/Getting started.md new file mode 100644 index 000000000..f4ec2b440 --- /dev/null +++ b/docs/Cakeshop/Getting started.md @@ -0,0 +1,147 @@ +## Quickstart +### Requirements + +* Java 8+ +* Java app server (Tomcat, Jetty, etc) [Optional] + +### Running via Spring Boot + +* Download WAR file (Binary packages are available for macOS, Windows, and Linux platforms on the [releases](https://github.com/jpmorganchase/cakeshop/releases) page. +) +* Run `java -jar cakeshop.war` +* Navigate to [http://localhost:8080/](http://localhost:8080/) + +*Note: when running in Windows, -Dgeth.node=geth must be specified as Quorum is not yet available on Windows OS* + +### Running via App Server + +* Download WAR file +* Put in `/webapps` folder of your app server +* Add Java system property `-Dspring.profiles.active=local` to startup script (`setenv.sh` for tomcat) +* Start app server +* Navigate to [http://localhost:8080/](http://localhost:8080/) (default port is usually 8080) + +*Note: when running in Windows, -Dgeth.node=geth must be specified as Quorum is not yet available on Windows OS* + +### Running modes + +There are a few ways in which you can run Cakeshop (see the sections below for details on each, as well as [configuration](https://github.com/jpmorganchase/cakeshop/blob/master/docs/configuration.md#geth) page): + + 1. **Default mode**: _Used when you want Cakeshop to start up an Ethereum node._ + + Running Cakeshop in the Default mode will start up Cakeshop and also start running a regular geth node (on a private/test network). + + 2. **'Attach/Unmanaged' mode**: _Used when you want to attach Cakeshop to an already running Ethereum-like node._ + + Running Cakeshop in 'Attach' a.k.a 'unmanaged' mode will initialize Cakeshop but not start it nor start any Ethereum node. Once Cakeshop initialization is complete you can configure it to use the RPC details of your running node . When you then start Cakeshop it will attach to your node. + +NOTE: if different parties on the network are using Cakeshop to deploy contracts to the network then they need to ensure they are using the same ContractRegistry address. See details below for setting up the ContractRegistry address in this case. + + 3. **Multi-Instance Set Up**: _Used when you want to run Cakeshop on more than one node in your network._ + + Cakeshop is currently designed such that a given instance of Cakeshop works directly with a single Ethereum-like node, however you can set up multiple instances of Cakeshop on the same machine (each which could either have been started in 'Default' mode or 'Attach' mode) such that each can talk to a different node. + +NOTE: you can use the Attach mode and/or Multi-Instance setup configuration to run Cakeshop on [Quorum](https://github.com/jpmorganchase/quorum) nodes. See below for connecting Cakeshop to the [7nodes](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes) network from the quorum-examples repo. + + +#### The below commands assume you have renamed the WAR file to cakeshop.war + +### Default Mode +1. In a terminal window run: + + ``` + $ cd path/to/cakeshop/war + $ java -jar cakeshop.war + ``` + +2. Open **http://localhost:8080/** in your browser (Firefox/Chrome supported) + +### Attach Mode +1. In a terminal window run: + + ``` + $ cd path/to/cakeshop/war + # The 'example' arg below will unpack the war file and set up the cakeshop data folders but will not actually start a node + $ java -jar cakeshop.war example + ``` +2. Navigate to path/to/cakeshop/war/data/local +3. Make the following edits to the application.properties file: + * set `geth.url` to the `rpcport` of your ethereum node, i.e. if your geth `rpcport` is 22001 then `geth.url=http\://localhost\:22001` + * ensure `geth.auto.start` is set to `false` + * ensure `geth.auto.stop` is set to `false` +4. Run: + + ``` + $ java -jar cakeshop.war + ``` +5. Open **http://localhost:8080/** in your browser (Firefox/Chrome supported) + +### Multi-Instance Setup + +Although Cakeshop currently has a one-to-one mapping with the underlying Ethereum-like node that it connects to, it is possible to have multiple Cakeshop instances running on the same machine, each connecting to a different Ethereum-like node. The best way to achieve this is to create separate Cakeshop folders for each node and then attach to each separately. You should also configure the ContractRegistry address as per the below: + +> ** Cakeshop ContractRegistry contract** + +>Cakeshop deploys a ContractRegistry contract upon start up that is used to track those contracts that have been deployed to the chain using Cakeshop or the Cakeshop APIs. When running a multi-instance setup, you'll want to ensure that each instance of Cakeshop references the same ContractRegistry contract in order that each provides a consistent view within the Contracts Explorer. + +>There are two cmd flags that can be set to achieve this: + +> * `CAKESHOP_SHARED_CONFIG` (recommended): When this flag is set, Cakeshop will try to load a file called 'shared.properties' and read the ContractRegistry address from it. If the file doesn't exist, Cakeshop will deploy the ContractRegistry contract, create this file and store the address in the file. + +> USAGE: `$ CAKESHOP_SHARED_CONFIG="{fileLocation}" java -jar cakeshop.war` + +> * `CAKESHOP_REGISTRY_ADDR`: This flag will directly override whatever ContractRegistry address is configured (or not) and run with that address. Using this flag doesn't change any local Cakeshop settings nor save this address to file and so you would have to run with this flag again to use this address again. + +> USAGE: `$ CAKESHOP_REGISTRY_ADDR="0xabcdefgh.." java -jar cakeshop.war` + + +1. In terminal window 1 run: + + ``` + mkdir myNetwork && cd myNetwork + cp path/to/cakeshop/download /myNetwork + cd myNetwork + mkdir node1 node2 + cd node1 + CAKESHOP_SHARED_CONFIG=".." java -jar ../cakeshop.war example + ``` + +2. Assuming you want to attach to an existing node, navigate to /myNetwork/node1/ and edit **application.properties** per the instructions for [attach mode](#attach-mode) as described above + +3. In terminal window 2 run: + + ``` + cd myNetwork/node2 + CAKESHOP_SHARED_CONFIG=".." java -jar ../cakeshop.war example + ``` + +4. Navigate to myNetwork/node2 and edit **application.properties** per the instructions for [attach mode](#attach-mode) as described above +5. In terminal window 1 run: + + ``` + CAKESHOP_SHARED_CONFIG=".." java -jar ../cakeshop.war + ``` + +6. In terminal window 2 run: + + ``` + CAKESHOP_SHARED_CONFIG=".." java -Dserver.port=8081 -jar cakeshop.war # Cakeshop will now be available on localhost:8081 + ``` + +7. In browser window 1 open http://localhost:8080/ + +8. In browser window 2 open http://localhost:8081/ + +### Running Cakeshop on quorum-examples +You can use the 'Attach' mode to use Cakeshop to explore the quorum-examples [7nodes](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes) network. + +To do so: + +1. Follow the instructions in the [7nodes](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes) example to start the 7nodes network (running vagrant up, init.sh, start.sh etc.) +2. Follow the instructions listed under the [Attach](#attach-mode) mode as described above, using the `rpcport` of the node you want to explore as found in the 7nodes [start.sh](https://github.com/jpmorganchase/quorum-examples/blob/master/examples/7nodes/start.sh) file. Equally, follow the [Multi-Instance](#multi-instance-setup) setup to attach to more than one of the Quorum nodes. + +### Confirming Cakeshop Start Up +In all cases, Cakeshop will be running once you see the below image, which shows the Cakeshop build and url that you can access that instance of Cakeshop on: + +![image](https://raw.githubusercontent.com/jpmorganchase/cakeshop-docs/master/images/happylion.png) + diff --git a/docs/Cakeshop/Overview.md b/docs/Cakeshop/Overview.md new file mode 100644 index 000000000..a3a4c2d9c --- /dev/null +++ b/docs/Cakeshop/Overview.md @@ -0,0 +1,21 @@ +## What is it? + +[Cakeshop](https://github.com/jpmorganchase/cakeshop) is a set of tools and APIs for working with [Ethereum](https://ethereum.org/)-like ledgers, packaged as a Java web application archive (WAR) that gets you up and running in under 60 seconds. + +Cakeshop can either start up a geth node, which you can then interact with using the Cakeshop front-end, or it can be connected to an Ethereum-like node, such as Quorum, that you already have running. A given Cakeshop instance connects with one node on the blockchain network you connect to. + +![image](console.png) + +Out of the box you get: + + +* **Node Management** - Fully functioning Ethereum node (via geth), setting up a cluster +* **Blockchain Explorer** - view transactions, blocks and contracts, and see historical contract state at a point in time +* **Admin Console** - start & stop nodes, create a cluster and view the overall status of your network +* **Peer Management** - easily discover, add and remove peers +* **Solidity Sandbox** - develop, compile, deploy and interact with Solidity smart contracts + +It provides tools for managing a local blockchain node, setting up clusters, +exploring the state of the chain, and working with contracts. + +The Cakeshop package includes the [tessera](https://github.com/jpmorganchase/tessera) and [constellation](https://github.com/jpmorganchase/constellation) transaction managers, a [Solidity](https://solidity.readthedocs.org/en/latest/) compiler, and all dependencies. Cakeshop will download the latest version of [quorum](https://github.com/jpmorganchase/quorum) and bootnode from [geth](https://github.com/ethereum/go-ethereum) (to use a different version, see [here](docs/configuration.md#custom-quorum-binaries)) diff --git a/docs/Cakeshop/console.png b/docs/Cakeshop/console.png new file mode 100644 index 000000000..7694032d2 Binary files /dev/null and b/docs/Cakeshop/console.png differ diff --git a/docs/Getting Started/api.md b/docs/Getting Started/api.md index 1df0aa8cc..4383a2140 100644 --- a/docs/Getting Started/api.md +++ b/docs/Getting Started/api.md @@ -70,13 +70,14 @@ __Important:__ Please note that before calling this API, a `storeraw` api need t - `privateFor`: `List` - When sending a private transaction, an array of the recipients' base64-encoded public keys. 3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details. - ##### Returns +##### Returns `String` - The 32 Bytes transaction hash as HEX string. If the transaction was a contract creation use [web3.eth.getTransactionReceipt()](#web3ethgettransactionreceipt) to get the contract address, after the transaction was mined. - ##### Example - ```js +##### Example + +```js var Tx = require('ethereumjs-tx'); var privateKey = new Buffer('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex') var rawTx = { @@ -97,7 +98,7 @@ __Important:__ Please note that before calling this API, a `storeraw` api need t if (!err) console.log(hash); // "0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385" }); - ``` +``` diff --git a/docs/Getting Started/running.md b/docs/Getting Started/running.md index 77f0fcbe0..a3e1d4f6c 100644 --- a/docs/Getting Started/running.md +++ b/docs/Getting Started/running.md @@ -192,6 +192,7 @@ In Quorum, transactions are considered private if the `v` parameter is set to `3 If you are running a version prior to version 2.1.0, EIP-155 signing is not used, thus a chain ID of `1` was allowed; you will need to change this using `geth init` before running an updated version. +# Zero Knowledge Work ## ZSL Proof of Concept J.P. Morgan and the Zcash team partnered to create a proof of concept (POC) implementation of ZSL for Quorum, which enables the issuance of digital assets using ZSL-enabled public smart contracts (z-contracts). We refer to such digital assets as “z-tokens”. Z-tokens can be shielded from public view and transacted privately. Proof that a shielded transaction has been executed can be presented to a private contract, thereby allowing the private contract to update its state in response to shielded transactions that are executed using public z-contracts. @@ -200,6 +201,15 @@ This combination of Constellation/Tessera’s private contracts with ZSL’s z-c For more information, see the [ZSL](../../ZSL) page of this wiki. +## Anonymous Zether + +This is a private payment system, an _anonymous_ extension of Bünz, Agrawal, Zamani and Boneh's [Zether protocol](https://crypto.stanford.edu/~buenz/papers/zether.pdf). + +The outlines of an anonymous approach are sketched in the authors' original manuscript. We develop an explicit proof protocol for this extension, described in the technical note [AnonZether.pdf](https://github.com/jpmorganchase/anonymous-zether/blob/master/docs/AnonZether.pdf). We also provide a full implementation of the anonymous protocol (including a proof generator, verification contracts, and a client / front-end). + +For more information, see the [Anonymous Zether](https://github.com/jpmorganchase/anonymous-zether/) repo. + +# Quorum Genesis Options ## Configurable transaction size: Quorum allows operators of blockchains to increase maximum transaction size of accepted transactions via the genesis block. The Quorum default is currently increased to `64kb` from Ethereum's default `32kb` transaction size. This is configurable up to `128kb` by adding `txnSizeLimit` to the config section of the genesis file: @@ -213,3 +223,15 @@ Quorum allows operators of blockchains to increase maximum transaction size of a } ``` +## Contract code size: + +Quorum allows operators of blockchains to increase maximum contract code size of accepted smart contracts via the genesis block. The Quorum default is currently increased to `32kb` from Ethereum's default `24kb` contract code size. This is configurable up to `128kb` by adding `maxCodeSize` to the config section of the genesis file: + +``` json +"config": { + "chainId": 10, + "isQuorum":true. + ... + "maxCodeSize": 128 +} +``` diff --git a/docs/Privacy/Tessera/Configuration/Configuration Overview.md b/docs/Privacy/Tessera/Configuration/Configuration Overview.md index d61139755..bf33ac23d 100644 --- a/docs/Privacy/Tessera/Configuration/Configuration Overview.md +++ b/docs/Privacy/Tessera/Configuration/Configuration Overview.md @@ -181,3 +181,17 @@ It is possible to configure a node that will be sent a copy of every transaction --- +### Remote-Key-Validation +Tessera provides an API `/partyinfo` on Tessera P2P server to discover all the peers in the network. In order to prevent attackers trying to inject malicious addresses against public keys, where they will try to assign the address to direct private transactions to them instead of the real owner of the key, we have added a feature to enable node level validation on the remote key that checks the remote node does in fact own the keys that were advertised. Only after the keys are validated with the remote node to ensure they own them, the keys are added to the local network info (partyinfo) store. + +Default configuration for this is `false` as this is BREAKABLE change to lower versions to Tessera 0.10.0. To enable this, simple set below parameter to true in the configuration: + +``` + "features": { + "enableRemoteKeyValidation": true + } +``` + +--- + + diff --git a/docs/Privacy/Tessera/Configuration/Sample Configuration.md b/docs/Privacy/Tessera/Configuration/Sample Configuration.md index 8b77537e3..83a191525 100644 --- a/docs/Privacy/Tessera/Configuration/Sample Configuration.md +++ b/docs/Privacy/Tessera/Configuration/Sample Configuration.md @@ -4,6 +4,8 @@ Tessera configuration varies by version as new features are added or changed. Be | Version | | ------------- | -| [0.9 - latest release](../Tessera%20v0.9%20sample%20settings) | +| [0.10 - latest release](../Tessera%20v0.10.0%20sample%20settings) | +| [0.9](../Tessera%20v0.9%20sample%20settings) | | [0.8](../Tessera%20v0.8%20sample%20settings) | | [0.7.3](../Tessera%20v0.7.3%20sample%20settings) | + diff --git a/docs/Privacy/Tessera/Configuration/Tessera v0.10.0 sample settings.md b/docs/Privacy/Tessera/Configuration/Tessera v0.10.0 sample settings.md new file mode 100644 index 000000000..58a6fe5ca --- /dev/null +++ b/docs/Privacy/Tessera/Configuration/Tessera v0.10.0 sample settings.md @@ -0,0 +1,139 @@ +**Changes:** +- Added configuration for remote key validation.Default is set to false + +e.g. +```json + "unixSocketFile": "Path", + "features": { + "enableRemoteKeyValidation": false + } +``` + +**Sample:** + +```json +{ + "useWhiteList": "boolean", + "jdbc": { + "url": "String", + "username": "String", + "password": "String" + }, + "serverConfigs": [ + { + "app": "ENCLAVE", + // Defines us using a remote enclave, leave out if using built-in enclave + "enabled": true, + "serverAddress": "http://localhost:9081", + //Where to find the remote enclave + "communicationType": "REST" + }, + { + "app": "ThirdParty", + "enabled": true, + "serverAddress": "http://localhost:9081", + "bindingAddress": "String - url with port e.g. http://127.0.0.1:9081", + "communicationType": "REST" + }, + { + "app": "Q2T", + "enabled": true, + "serverAddress": "unix:/tmp/tm.ipc", + "communicationType": "REST" + }, + { + "app": "P2P", + "enabled": true, + "serverAddress": "http://localhost:9001", + "bindingAddress": "String - url with port e.g. http://127.0.0.1:9001", + "sslConfig": { + "tls": "enum STRICT,OFF", + "generateKeyStoreIfNotExisted": "boolean", + "serverKeyStore": "Path", + "serverTlsKeyPath": "Path", + "serverTlsCertificatePath": "Path", + "serverKeyStorePassword": "String", + "serverTrustStore": "Path", + "serverTrustCertificates": [ + "Path..." + ], + "serverTrustStorePassword": "String", + "serverTrustMode": "Enumeration: CA, TOFU, WHITELIST, CA_OR_TOFU, NONE", + "clientKeyStore": "Path", + "clientTlsKeyPath": "Path", + "clientTlsCertificatePath": "Path", + "clientKeyStorePassword": "String", + "clientTrustStore": "Path", + "clientTrustCertificates": [ + "Path..." + ], + "clientTrustStorePassword": "String", + "clientTrustMode": "Enumeration: CA, TOFU, WHITELIST, CA_OR_TOFU, NONE", + "knownClientsFile": "Path", + "knownServersFile": "Path" + }, + "communicationType": "REST" + } + ], + "peer": [ + { + "url": "url e.g. http://127.0.0.1:9000/" + } + ], + "keys": { + "passwords": [ + "String..." + ], + "passwordFile": "Path", + "azureKeyVaultConfig": { + "url": "Azure Key Vault url" + }, + "hashicorpKeyVaultConfig": { + "url": "Hashicorp Vault url", + "approlePath": "String (defaults to 'approle' if not set)", + "tlsKeyStorePath": "Path to jks key store", + "tlsTrustStorePath": "Path to jks trust store" + }, + "keyData": [ + { + "config": { + "data": { + "aopts": { + "variant": "Enum : id,d or i", + "memory": "int", + "iterations": "int", + "parallelism": "int" + }, + "bytes": "String", + "snonce": "String", + "asalt": "String", + "sbox": "String", + "password": "String" + }, + "type": "Enum: argon2sbox or unlocked. If unlocked is defined then config data is required. " + }, + "privateKey": "String", + "privateKeyPath": "Path", + "azureVaultPrivateKeyId": "String", + "azureVaultPrivateKeyVersion": "String", + "publicKey": "String", + "publicKeyPath": "Path", + "azureVaultPublicKeyId": "String", + "azureVaultPublicKeyVersion": "String", + "hashicorpVaultSecretEngineName": "String", + "hashicorpVaultSecretName": "String", + "hashicorpVaultSecretVersion": "Integer (defaults to 0 (latest) if not set)", + "hashicorpVaultPrivateKeyId": "String", + "hashicorpVaultPublicKeyId": "String" + } + ] + }, + "alwaysSendTo": [ + "String..." + ], + "unixSocketFile": "Path", + "features": { + "enableRemoteKeyValidation": false + } +} +``` diff --git a/docs/Privacy/Tessera/How Tessera Works.md b/docs/Privacy/Tessera/How Tessera Works.md index 35563bf67..a68316afe 100644 --- a/docs/Privacy/Tessera/How Tessera Works.md +++ b/docs/Privacy/Tessera/How Tessera Works.md @@ -6,23 +6,24 @@ Below is a description of how Private Transactions are processed in Quorum: In this example, Party A and Party B are party to Transaction AB, whilst Party C is not. -1. Party A sends a Transaction to their Quorum Node, specifying the Transaction payload and setting `privateFor` to be the public keys for Parties A and B -2. Party A's Quorum Node passes the Transaction on to its paired Transaction Manager, requesting for it to store the Transaction payload -3. Party A's Transaction Manager makes a call to its associated Enclave to validate the sender and encrypt the payload -4. Party A's Enclave checks the private key for Party A and, once validated, performs the Transaction conversion. This entails: +1. Party A sends a Transaction to their Quorum Node, specifying the Transaction payload and setting `privateFor` to be the public keys for Parties A and B (Party A is optional) +1. Party A's Quorum Node passes the Transaction on to its paired Transaction Manager, requesting for it to store the Transaction payload +1. Party A's Transaction Manager makes a call to its associated Enclave to validate the sender and encrypt the payload +1. Party A's Enclave checks the private key for Party A and, once validated, performs the Transaction conversion. This entails: - 1. generating a symmetric key and a random Nonce - 1. encrypting the Transaction payload and Nonce with the symmetric key from i. - 1. calculating the SHA3-512 hash of the encrypted payload from ii. - 1. iterating through the list of Transaction recipients, in this case Parties A and B, and encrypting the symmetric key from i. with the recipient's public key (PGP encryption) - 1. returning the encrypted payload from step ii., the hash from step iii. and the encrypted keys (for each recipient) from step iv. to the Transaction Manager -5. Party A's Transaction manager then stores the encrypted payload (encrypted with the symmetric key) and encrypted symmetric key using the hash as the index, and then securely transfers (via HTTPS) the hash, encrypted payload, and encrypted symmetric key that has been encrypted with Party B's public key to Party B's Transaction Manager. Party B's Transaction Manager responds with an Ack/Nack response. Note that if Party A does not receive a response/receives a Nack from Party B then the Transaction will not be propagated to the network. It is a prerequisite for the recipients to store the communicated payload. -6. Once the data transmission to Party B's Transaction Manager has been successful, Party A's Transaction Manager returns the hash to the Quorum Node which then replaces the Transaction's original payload with that hash, and changes the transaction's `V` value to 37 or 38, which will indicate to other nodes that this hash represents a private transaction with an associated encrypted payload as opposed to a public transaction with nonsensical bytecode. -7. The Transaction is then propagated to the rest of the network using the standard Ethereum P2P Protocol. -8. A block containing Transaction AB is created and distributed to each Party on the network. -9. In processing the block, all Parties will attempt to process the Transaction. Each Quorum node will recognise a `V` value of 37 or 38, identifying the Transaction as one whose payload requires decrypting, and make a call to their local Transaction Manager to determine if they hold the Transaction (using the hash as the index to look up). -10. Since Party C does not hold the Transaction, it will receive a `NotARecipient` message and will skip the Transaction - it will not update its Private StateDB. Party A and B will look up the hash in their local Transaction Managers and identify that they do hold the Transaction. Each will then make a call to its Enclave, passing in the Encrypted Payload, Encrypted symmetric key and Signature. -11. The Enclave validates the signature and then decrypts the symmetric key using the Party's private key that is held in The Enclave, decrypts the Transaction Payload using the now-revealed symmetric key and returns the decrypted payload to the Transaction Manager. -12. The Transaction Managers for Parties A and B then send the decrypted payload to the EVM for contract code execution. This execution will update the state in the Quorum Node's Private StateDB only. NOTE: once the code has been executed it is discarded so is never available for reading without going through the above process. + 1. generating a random master key (RMK) and a random Nonce + 1. encrypting the Transaction payload with the nonce and RMK from step a. + 1. iterating through the list of transaction recipients, in this case parties A and B, and encrypting the RMK from a. with the shared key derived from Party A's private key and the recipient's public key, along with another randomly generated nonce. Each encrypted RMK is unique for each recipient and will only be shared with the respective recipient along with encrypted payload. + 1. returning the encrypted payload from step b. and all encrypted RMKs from step c. to the Transaction Manager + +1. Party A's Transaction Manager calculates the SHA3-512 hash of the encrypted payload then stores the encrypted payload and encrypted RMKs against the hash in the database +1. Party A's Transaction Manager then securely transfers (via HTTPS) the encrypted payload, and RMK that has been encrypted with shared key from previous step 4.c, the nonce's to Party B's Transaction Manager. Party B's Transaction Manager responds with an Ack/Nack response. Note that if Party A does not receive a response/receives a Nack from Party B then the Transaction will not be propagated to the network. It is a prerequisite for the recipients to store the communicated payload. +1. Once the data transmission to Party B's Transaction Manager has been successful, Party A's Transaction Manager returns the hash to the Quorum Node which then replaces the Transaction's original payload with that hash, and changes the transaction's `V` value to 37 or 38, which will indicate to other nodes that this hash represents a private transaction with an associated encrypted payload as opposed to a public transaction with nonsensical bytecode. +1. The Transaction is then propagated to the rest of the network using the standard Ethereum P2P Protocol. +1. A block containing Transaction AB is created and distributed to each Party on the network. +1. In processing the block, all Parties will attempt to process the Transaction. Each Quorum node will recognise a `V` value of 37 or 38, identifying the Transaction as one whose payload requires decrypting, and make a call to their local Transaction Manager to determine if they hold the Transaction (using the hash as the index to look up). +1. Since Party C does not hold the Transaction, it will receive a `NotARecipient` message and will skip the Transaction - it will not update its Private StateDB. Party A and B will look up the hash in their local Transaction Managers and identify that they do hold the Transaction. Each will then make a call to its Enclave, passing in the Encrypted Payload, Encrypted symmetric key and Signature. +1. The Enclave validates the signature and then decrypts the symmetric key using the Party's private key that is held in The Enclave, decrypts the Transaction Payload using the now-revealed symmetric key and returns the decrypted payload to the Transaction Manager. +1. The Transaction Managers for Parties A and B then send the decrypted payload to the EVM for contract code execution. This execution will update the state in the Quorum Node's Private StateDB only. NOTE: once the code has been executed it is discarded so is never available for reading without going through the above process. diff --git a/docs/Privacy/Tessera/Usage/Interface & API.md b/docs/Privacy/Tessera/Usage/Interface & API.md index 276a49798..adf286a55 100644 --- a/docs/Privacy/Tessera/Usage/Interface & API.md +++ b/docs/Privacy/Tessera/Usage/Interface & API.md @@ -28,6 +28,7 @@ The following endpoints are advertised on this interface: * `/push` * `/resend` * `/partyinfo` +* `/partyinfo/validate` ### Third Party - Public API @@ -89,6 +90,10 @@ The following endpoints are advertised on this API: - GET: Request public keys/url of all known peer nodes. - POST: accepts a stream that contains the caller node's network information, and returns a merged copy with the callee node's network information +**`partyinfo/validate`** - _Validates a node possesses a key_ + +- Will request a node to decrypt a transaction in order to prove that it has access to the private part of its advertised public key. + **`sendraw`** - _Send transaction bytestring_ - Send transaction payload bytestring from Quorum to Tessera node. Tessera sends the transaction hash in the response back. diff --git a/mkdocs.yml b/mkdocs.yml index 426f11442..b0597c249 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -71,7 +71,11 @@ nav: - How it works: Privacy/Constellation/How constellation works.md - Sample Configuration: Privacy/Constellation/Sample Configuration.md - Running Constellation: Privacy/Constellation/Installation & Running.md - - Product Roadmap: roadmap.md + - Cakeshop: + - Overview: Cakeshop/Overview.md + - Getting Started: Cakeshop/Getting started.md + - Cakeshop FAQ: Cakeshop/Cakeshop FAQ.md + - Product Roadmap: roadmap.md - FAQ: FAQ.md theme: diff --git a/params/config.go b/params/config.go index 9322edd8e..436a383a0 100644 --- a/params/config.go +++ b/params/config.go @@ -132,19 +132,19 @@ var ( // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32} + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32} // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil, false, 32} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil, false, 32, 32} - TestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32} + TestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil, false, 32, 32} TestRules = TestChainConfig.Rules(new(big.Int)) - QuorumTestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, nil, common.Hash{}, nil, nil, nil, nil, nil, new(EthashConfig), nil, nil, true, 64} + QuorumTestChainConfig = &ChainConfig{big.NewInt(10), big.NewInt(0), nil, false, nil, common.Hash{}, nil, nil, nil, nil, nil, new(EthashConfig), nil, nil, true, 64, 32} ) // TrustedCheckpoint represents a set of post-processed trie roots (CHT and @@ -190,6 +190,7 @@ type ChainConfig struct { IsQuorum bool `json:"isQuorum"` TransactionSizeLimit uint64 `json:"txnSizeLimit"` + MaxCodeSize uint64 `json:"maxCodeSize"` } // EthashConfig is the consensus engine configs for proof-of-work based sealing. @@ -251,10 +252,15 @@ func (c *ChainConfig) String() string { } func (c *ChainConfig) IsValid() error { + if c.TransactionSizeLimit < 32 || c.TransactionSizeLimit > 128 { return errors.New("Genesis transaction size limit must be between 32 and 128") } + if c.MaxCodeSize < 24 || c.MaxCodeSize > 128 { + return errors.New("Genesis max code size must be between 24 and 128") + } + return nil } diff --git a/params/version.go b/params/version.go index 72a081ab3..d6af28e9e 100644 --- a/params/version.go +++ b/params/version.go @@ -28,7 +28,7 @@ const ( QuorumVersionMajor = 2 QuorumVersionMinor = 2 - QuorumVersionPatch = 4 + QuorumVersionPatch = 5 ) // Version holds the textual version string.